001    package calhoun.analysis.crf.io;
002    
003    import java.io.BufferedReader;
004    import java.io.IOException;
005    import java.io.Writer;
006    import java.util.Map;
007    
008    import org.apache.commons.logging.Log;
009    import org.apache.commons.logging.LogFactory;
010    
011    import calhoun.analysis.crf.io.IntervalInputSequence.IntervalRangeMapValue;
012    import calhoun.util.Assert;
013    import calhoun.util.RangeMap;
014    
015    /** an input component used to read in values that are similar for long intervals.
016     * Each input sequence is a line which looks like "<code>(164716,215910,-,1.0)(194048,218199,-,1.0)...</code>".
017     * Takes this input and creates an {@link IntervalInputSequence}.
018     * <p>
019     * This input component is can be used in a regular input handler or as part of an {@link InputHandlerInterleaved}.
020     */
021    public class IntervalInput extends InterleavedInputComponentBase {
022            private static final long serialVersionUID = 8110670530135286052L;
023            private static final Log log = LogFactory.getLog(IntervalInput.class);
024    
025            public boolean read(BufferedReader r, Map<String, InputSequence<?>> output) throws IOException {
026                    String temp = r.readLine();
027                    String inputName = temp;
028                    temp = r.readLine();
029                    int inputLength;
030                    try {
031                            inputLength = Integer.parseInt(temp);
032                    } catch (Exception e){
033                            throw new RuntimeException("Offending line was : " + temp);
034                    }
035                    log.debug("Length of " + inputName + "   is  " + inputLength);  
036                    
037                    RangeMap rmplus = new RangeMap();
038                    RangeMap rmminus = new RangeMap();
039                    
040                    String bigLine = r.readLine();
041                    // Parse lines like this: (164716,215910,-,1.0)(194048,218199,-,1.0)    
042                    
043                    String[] fields = bigLine.split("[(]");
044                    for (int k=1; k<fields.length; k++) {
045                            String[] rings = fields[k].split("[,)]");
046    
047                            int start = Integer.parseInt(rings[0]);
048                            int stop = Integer.parseInt(rings[1]);
049                            char strand = rings[2].charAt(0);
050                            double val = Double.parseDouble(rings[3]);
051    
052                            IntervalRangeMapValue irmv = new IntervalRangeMapValue(start,stop,val);
053                            if (strand=='+') {
054                                    irmv.insertIntoRangeMap(rmplus);
055                            } else if (strand=='-') {
056                                    irmv.insertIntoRangeMap(rmminus);                       
057                            } else { Assert.a(false); }
058                    }
059                    InputSequence<?> inputSeq = new IntervalInputSequence(rmplus, rmminus, inputName, inputLength);
060                    output.put(name, inputSeq);
061                    return true;
062            }
063    
064            public void write(Writer w, Map<String, ? extends InputSequence<?>> data) throws IOException {
065                    IntervalInputSequence seq = (IntervalInputSequence) data;
066                    w.write(seq.inputName + "\n");
067                    w.write("" + seq.inputLength + "\n");
068                    Object[] rmplusList = seq.rmplus.getObjectList().values().toArray();
069                    for (int i=0; i<rmplusList.length; i++) {
070                            w.write(((IntervalRangeMapValue) rmplusList[i]).toStringStrand("+"));
071                    }
072                    
073                    Object[] rmminusList = seq.rmminus.getObjectList().values().toArray();
074                    for (int i=0; i<rmminusList.length; i++) {
075                            w.write(((IntervalRangeMapValue) rmminusList[i]).toStringStrand("+"));
076                    }               
077                    w.write("\n");
078            }
079    }