root/grails-app/controllers/importer/MeasurementTypeImporterController.groovy @ 182

Revision 182, 9.1 KB (checked in by adem.bilican@…, 3 years ago)

correction for text input into importer

Line 
1package importer
2import data.SimpleAssayMeasurementType
3import data.*
4
5//import org.apache.poi.hssf.usermodel.*
6import org.apache.poi.poifs.filesystem.POIFSFileSystem
7import org.apache.poi.ss.usermodel.DataFormatter
8import org.apache.poi.hssf.usermodel.HSSFWorkbook
9import org.apache.commons.codec.*
10import org.apache.poi.ss.usermodel.*
11
12/**
13 * @author Adem and Jahn
14 * @since 20100602
15 */
16
17class MeasurementTypeImporterController {
18
19    def ImporterService
20    def searchableService
21    def fileService
22
23    def index = {
24        String.metaClass.mostSimilarTo = { mostSimilar(delegate, it) }
25        redirect(action: 'pages')
26    }
27
28    def pagesFlow = {
29
30        onStart {
31            flow.page = 0
32            flow.pages = [
33                [title: 'Import data'],
34                [title: 'Show data'],
35                [title: 'Done']
36            ]
37        }
38
39        mainPage {
40            render(view:'/measurementTypeImporter/importMain')
41            onRender {
42                flow.page=0
43                next()
44            }
45            on("next"){
46                success()
47            }.to"importData"
48        }
49
50        importData{
51            render(view:'_importData')
52            onRender {
53                flow.page=1
54            }
55            on('next'){
56                flash.errors = false
57                def tabbedTable = params['measurementTypeData']
58                // there is user input in the text area
59                if( (tabbedTable.replaceAll("^\\s+", "").size() > 0) && (params['file'] == "null" ) ) {   
60                    flow.tab = tabbedTable
61                    this.parseData(ImporterService, flow.tab, flow)
62                    flow.file = params['file']
63                    success()
64                }
65                // there is a file
66                else if ((tabbedTable.replaceAll("^\\s+", "").size() == 0) && (params['file'] != "null" )) {
67                    try{
68                        this.parseData(ImporterService, fileService.get(params['file']) ,flow)
69                        flow.file = params['file']
70                        success()
71                    }
72                    catch (Exception e){
73                        fileService.delete(params['file'])
74                        flash.errors = "File Error : Please check the file integrity. It should be an Excel sheet."
75                        error()
76                    }
77                }
78                // catch error if there is nothing to do
79                else if ((tabbedTable.replaceAll("^\\s+", "").size() == 0) && (params['file'] == "null" ))
80                {
81                    flash.errors = 'No user input : Please paste your data or select a file'
82                    error()
83                }
84                //catch error if there is too much information
85                else if ((tabbedTable.replaceAll("^\\s+", "").size() > 0) && (params['file'] != "null" ))
86                {
87                    flash.errors = 'Too much information : Please paste your data OR select a file'
88                    error()
89                }
90            }.to('showData')
91        }
92
93        showData{
94            render(view:'_showData')
95            onRender{
96                flow.page=2
97            }
98            on('next'){
99                flash.errors=false
100                try {
101                    this.isValid(params['att'],flow.datamatrix,flash,flow)
102                    fileService.delete(flow.file)
103                    success()
104
105                }
106                catch (Exception e) {
107                    flash.errors = 'Error : Please check your selection'
108                    fileService.delete(flow.file)
109                    error()
110                }
111            }.to('done')
112            on('previous').to('importData')
113        }
114
115        done {
116            render(view:'_done')
117            onRender {
118                flow.page=3
119            }
120        }
121    }
122
123    /*
124     * parseData will parse the pasted tab-delimited data
125     */
126    def parseData(ImporterService, tabDelimited, flow){
127        def headersList= []
128        def datamatrix = []
129        def wb = getWorkBook(tabDelimited)
130        // getHeader contains information about headers
131        for (header in ImporterService.getHeader(wb, 0)){
132            headersList.add(header.name)
133        }
134        // getDatamatrix contains the data for each line
135        for (line in ImporterService.getDatamatrix(wb,0,5,1)){
136            def lines = []
137            for (box in line ){
138                lines.add(box.toString())
139            }
140            datamatrix.add(lines)
141        }
142        flow.datamatrix = datamatrix
143        flow.headers = headersList
144    }
145
146    /* Create a Horrible Style Sheet Framework Workbook from tab-delimited string.
147     *
148     * @param  tabbed:  A tab-delimited string representing a table as by copy and paste from
149     *                  an Excell sheet.
150     * @return HSSFWorkbook containing the same table.
151     *
152     */
153    private Workbook getWorkBook( tabbed ) {
154        def wb
155        if (tabbed instanceof File) {
156            wb = WorkbookFactory.create(new FileInputStream(tabbed))
157        }
158        else {
159            wb = new HSSFWorkbook()
160        }
161        def createHelper = wb.getCreationHelper()
162        def sheet = wb.createSheet("sheet")
163
164        def rowIndex = 0
165        tabbed.splitEachLine("\t") { line ->
166            def row = sheet.createRow((short)rowIndex++)
167            def colIndex = 0
168            line.each{ entry ->
169                def cell = row.createCell(colIndex++).setCellValue(entry)
170            }
171        }
172        return wb
173    }
174
175    // validate the measurementst type before adding to the database
176    private isValid(attributes,datamatrix,flash,flow) {
177        def errors=false
178        def matrixToSave = [:]
179        def errorList = []
180        for(i in 0..attributes.size()-1){
181            def dataList= []
182            for (j in datamatrix){
183                dataList.add(j.getAt(i))
184            }
185            matrixToSave[attributes.getAt(i)] = dataList
186        }
187
188        for (i in 0..datamatrix.size()-1){
189
190            def typeExists = SimpleAssayMeasurementType.find("from SimpleAssayMeasurementType t where t.name='${matrixToSave.getAt("Name").getAt(i).toString()}'")
191
192            if (typeExists){
193                errorList.add(typeExists.name)
194            }
195            else {
196                def measurementType = new SimpleAssayMeasurementType(
197                    name: matrixToSave.getAt("Name").getAt(i).toString(),
198                    unit: (matrixToSave.getAt("Unit")!=null) ? matrixToSave.getAt("Unit").getAt(i).toString() : null,
199                    detectableLimit: (matrixToSave.getAt("Detectable Limit")!=null) ? matrixToSave.getAt("Detectable Limit").getAt(i).replaceAll(",",".").toFloat() : "0" ,
200                    referenceValues: (matrixToSave.getAt("Reference Values")!=null) ? matrixToSave.getAt("Reference Values").getAt(i).toString() : null ,
201                    isNew : ((matrixToSave.getAt("Is New")!=null) && (matrixToSave.getAt("Is New").getAt(i).toString()=="yes")) ? true : false ,
202                    isIntake : ((matrixToSave.getAt("Is Intake")!=null) && (matrixToSave.getAt("Is Intake").getAt(i).toString()=="yes")) ? true : false ,
203                    inSerum : ((matrixToSave.getAt("In Serum")!=null) && (matrixToSave.getAt("In Serum").getAt(i).toString()=="yes")) ? true : false ,
204                    isDrug : ((matrixToSave.getAt("Is Drug")!=null) && (matrixToSave.getAt("Is Drug").getAt(i).toString()=="yes")) ? true : false
205                )
206                measurementType.save(flush:true)
207            }
208
209        }
210        flow.errorList = errorList
211        if (errors){
212            flash.errors = "<html>The measurements type "+errorList+" already exists<br> Please edit your data </html>"
213        }
214        return !errors
215    }
216
217    // classes for fuzzy string matching
218    // <FUZZY MATCHING>
219    static def similarity(l_seq, r_seq, degree=2) {
220        def l_histo = countNgramFrequency(l_seq, degree)
221        def r_histo = countNgramFrequency(r_seq, degree)
222
223        dotProduct(l_histo, r_histo) /
224        Math.sqrt(dotProduct(l_histo, l_histo) *
225            dotProduct(r_histo, r_histo))
226    }
227
228    static def countNgramFrequency(sequence, degree) {
229        def histo = [:]
230        def items = sequence.size()
231
232        for (int i = 0; i + degree <= items; i++)
233        {
234            def gram = sequence[i..<(i + degree)]
235            histo[gram] = 1 + histo.get(gram, 0)
236        }
237        histo
238    }
239
240    static def dotProduct(l_histo, r_histo) {
241        def sum = 0
242        l_histo.each { key, value ->
243            sum = sum + l_histo[key] * r_histo.get(key, 0)
244        }
245        sum
246    }
247
248    static def stringSimilarity (l_str, r_str, degree=2) {
249        similarity(l_str.toLowerCase().toCharArray(),
250            r_str.toLowerCase().toCharArray(),
251            degree)
252    }
253
254    static def mostSimilar(pattern, candidates, threshold=0) {
255        def topScore = 0
256        def bestFit = null
257
258        candidates.each { candidate ->
259            def score = stringSimilarity(pattern, candidate)
260            if (score > topScore) {
261                topScore = score
262                bestFit = candidate
263            }
264        }
265
266        if (topScore < threshold)
267        bestFit = null
268
269        bestFit
270    }
271    // </FUZZY MATCHING>
272
273
274}
275
Note: See TracBrowser for help on using the browser.