/* =========================================================== * WFDB Java : Interface to WFDB Applications. * * =========================================================== * * (C) Copyright 2012, by Ikaro Silva * * Project Info: * Code: http://code.google.com/p/wfdb-java/ * WFDB: http://www.physionet.org/physiotools/wfdb.shtml * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * * * Original Author: Ikaro Silva * Contributor(s): -; * * Changes * ------- * Check: http://code.google.com/p/wfdb-java/list */ package org.physionet.wfdb.physiobank; import java.util.ArrayList; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.physionet.wfdb.Wfdbexec; public class PhysioNetRecord { private String name=new String(); private ArrayList signalStringList; private ArrayList signalList; private static Logger logger = Logger.getLogger(PhysioNetRecord.class.getName()); public PhysioNetRecord(String RecordName) throws Exception{ name=RecordName; signalStringList = new ArrayList(); signalList=new ArrayList(); setSignalList(); } public ArrayList getSignalStringList() { return signalStringList; } public void printRecord(){ for(PhysioNetSignal sig: signalList){ sig.printSignalInfo(); } } public void setSignalList() throws Exception{ setSignalList(null); } public void setSignalList(String descFilter) throws Exception { //Parse information from wfdbdesc to populate the record list String[] args=new String[1]; args[0]=name; Wfdbexec wfdbdesc = new Wfdbexec("wfdbdesc", Wfdbexec.customArchFlag); wfdbdesc.setArguments(args); logger.finest("\n\t***Executing wfdb command"); ArrayList tmpList= wfdbdesc.execToStringList(); String startTime=null; String lengthTime=null; String lengthSample=null; String samplingFrequency=null; PhysioNetSignal tmpSignal=null; //REGEXP Parsers String groupRegex="^Group (\\d+), Signal (\\d+):"; //Regex to parse something like: "Length: 30:05.556 (650000 sample intervals)" //TODO: find a way to make one single expression with optional day field String lengthRegex="Length:\\s+(\\d+:\\d+.\\d+)\\s+\\((\\d+)\\s+sample\\s+intervals\\)"; String lengthRegex2="Length:\\s+(\\d+:\\d+:\\d+.\\d+)\\s+\\((\\d+)\\s+sample\\s+intervals\\)"; Pattern groupPattern = Pattern.compile(groupRegex); Pattern lengthPattern = Pattern.compile(lengthRegex); Pattern lengthPattern2 = Pattern.compile(lengthRegex2); Matcher groupMatch=null; Matcher lengthMatch=null; logger.fine("parsing list, size= " + tmpList.size()); for(String i : tmpList){ logger.finest("parsing :" + i); if(i.startsWith("Starting time: ")){ startTime=i.replace("Starting time: ",""); } else if (i.startsWith("Length: ") && !(i.contains("Length: not specified")) ) { try{ //String should have a format similar to :Length: 30:05.556 (650000 sample intervals) lengthMatch=lengthPattern.matcher(i); if (!lengthMatch.find() ){ //Attempt second matcher for length lengthMatch=lengthPattern2.matcher(i); lengthMatch.find(); } if(! lengthMatch.group(1).isEmpty()) lengthTime=lengthMatch.group(1); if(! lengthMatch.group(2).isEmpty()) lengthSample=lengthMatch.group(2); } catch (IllegalStateException e){ System.err.println("Could not match : " +i ); System.err.println("Attempting to continue..."); } }else if (i.startsWith("Sampling frequency: ")) { samplingFrequency=i.replace("Sampling frequency: ",""); }else if (i.startsWith("Group ")) { if(tmpSignal != null){ if(descFilter == null){ signalList.add(tmpSignal); }else if(descFilter.equals(tmpSignal.getDescription())){ signalList.add(tmpSignal); } } tmpSignal=new PhysioNetSignal(signalList.size()+1,name); tmpSignal.setStartTime(startTime); tmpSignal.setLengthTime(lengthTime); tmpSignal.setLengthSamples(lengthSample); tmpSignal.setSamplingFrequency(samplingFrequency); groupMatch=groupPattern.matcher(i); groupMatch.find(); if(! groupMatch.group(1).isEmpty()) tmpSignal.setGroup(groupMatch.group(1)); if(! groupMatch.group(2).isEmpty()) tmpSignal.setSignalIndex(groupMatch.group(2)); }else if (i.startsWith(" File: ")) { tmpSignal.setFile(i.replace(" File: ","")); }else if (i.startsWith(" Description: ")) { tmpSignal.setDescription(i.replace(" Description: ","")); }else if (i.startsWith(" Gain: ")) { tmpSignal.setGain(i.replace(" Gain: ","")); }else if (i.startsWith(" Initial value: ")) { tmpSignal.setInitialValue(i.replace(" Initial value: ","")); }else if (i.startsWith(" Storage format: ")) { tmpSignal.setFormat(i.replace(" Storage format: ","")); }else if (i.startsWith(" I/O: ")) { tmpSignal.setIo(i.replace(" I/O: ","")); }else if (i.startsWith(" ADC resolution: ")) { tmpSignal.setAdcResolution(i.replace(" ADC resolution: ","")); }else if (i.startsWith(" ADC zero: ")) { tmpSignal.setAdcZero(i.replace(" ADC zero: ","")); }else if (i.startsWith(" Baseline: ")) { tmpSignal.setBaseline(i.replace(" Baseline: ","")); }else if (i.startsWith(" Checksum: ")) { tmpSignal.setCheckSum(i.replace(" Checksum: ","")); } } //end of for loop //Add last signal to list if(tmpSignal != null){ if(descFilter == null){ signalList.add(tmpSignal); }else if(descFilter.equals(tmpSignal.getDescription())){ signalList.add(tmpSignal); } } logger.fine("Done parsing!"); } public ArrayList getSignalList() { return signalList; } public String getRecordName(){ return name; } public static void main(String[] args) throws Exception { PhysioNetRecord re = new PhysioNetRecord(args[0]); ArrayList sg= re.getSignalList(); for(PhysioNetSignal mysig : sg) mysig.printSignalInfo(); } }