package ua.stu.scplib.structure;
import java.io.IOException;
import ua.stu.scplib.attribute.BinaryInputStream;
/**
* <p>A class to encapsulate the SCP-ECG Lead Definition section.</p>
*
* @author stu
*/
public class Section3 extends Section {
/**
* <p>Get a string name for this section.</p>
*
* @return a string name for this section
*/
public String getSectionName() { return "Lead Definition"; }
private static String[] leadNameDictionary = {
"Unspecified",
"I", // Einthoven
"II",
"V1",
"V2",
"V3",
"V4",
"V5",
"V6",
"V7",
"V2R", // 10
"V3R",
"V4R",
"V5R",
"V6R",
"V7R",
"X",
"Y",
"Z",
"CC5",
"CM5", // 20
"Left Arm",
"Right Arm",
"Left Leg",
"I (Frank)", // Frank
"E",
"C",
"A",
"M",
"F",
"H", // 30
"I -cal", // Einthoven
"II-cal",
"V1-cal",
"V2-cal",
"V3-cal",
"V4-cal",
"V5-cal",
"V6-cal",
"V7-cal",
"V2R-cal", // 40
"V3R-cal",
"V4R-cal",
"V5R-cal",
"V6R-cal",
"V7R-cal",
"X-cal",
"Y-cal",
"Z-cal",
"CC5-cal",
"CM5-cal", // 50
"Left Arm-cal",
"Right Arm-cal",
"Left Leg-cal",
"I-cal (Frank)", // Frank
"E-cal",
"C-cal",
"A-cal",
"M-cal",
"F-cal",
"H-cal", // 60
"III",
"aVR",
"aVL",
"aVF",
"-aVR",
"V8",
"V9",
"V8R",
"V9R",
"D (Nehb – Dorsal)", // 70
"A (Nehb – Anterior)",
"J (Nehb – Inferior)",
"Defibrillator lead: anterior-lateral",
"External pacing lead: anteriorposterior",
"A1 (Auxiliary unipolar lead 1)",
"A2 (Auxiliary unipolar lead 2)",
"A3 (Auxiliary unipolar lead 3)",
"A4 (Auxiliary unipolar lead 4)",
"V8-cal",
"V9-cal", // 80
"V8R-cal",
"V9R-cal",
"D-cal (cal for Nehb – Dorsal)",
"A-cal (cal for Nehb – Anterior)",
"J-cal (cal for Nehb – Inferior)" // 85
};
public static String getLeadName(int leadNumber) {
return (leadNumber > 0 && leadNumber<leadNameDictionary.length) ? leadNameDictionary[leadNumber] : "";
}
public static int getLeadNumber(String leadName) { // -1 = not found
for (int leadNumber=0; leadNumber<leadNameDictionary.length; ++leadNumber) {
if (leadNameDictionary[leadNumber].equals(leadName)) {
return leadNumber;
}
}
return -1;
}
private int numberOfLeads;
private int flagByte;
private boolean referenceBeatUsedForCompression;
private boolean reservedBit1;
private boolean leadsAllSimultaneouslyRecorded;
private int numberOfSimultaneouslyRecordedLeads;
private long[] startingSampleNumbers;
private long[] endingSampleNumbers;
private long[] numbersOfSamples;
private int[] leadNumbers;
private String[] leadNames;
public int getNumberOfLeads() { return numberOfLeads; }
public int getFlagByte() { return flagByte; }
public boolean getReferenceBeatUsedForCompression() { return referenceBeatUsedForCompression; }
public boolean getReservedBit1() { return reservedBit1; }
public boolean getLeadsAllSimultaneouslyRecorded() { return leadsAllSimultaneouslyRecorded; }
public int getNumberOfSimultaneouslyRecordedLeads() { return numberOfSimultaneouslyRecordedLeads; }
public long[] getStartingSampleNumbers() { return startingSampleNumbers; }
public long[] getEndingSampleNumbers() { return endingSampleNumbers; }
public long[] getNumbersOfSamples() { return numbersOfSamples; }
public int[] getLeadNumbers() { return leadNumbers; }
public String[] getLeadNames() {
if (leadNames == null) {
leadNames = new String[numberOfLeads];
for (int lead=0; lead<numberOfLeads; ++lead) {
leadNames[lead] = getLeadName(leadNumbers[lead]);
}
}
return leadNames;
}
public Section3(SectionHeader header) {
super(header);
}
public long read(BinaryInputStream i) throws IOException {
numberOfLeads=i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
flagByte = i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
referenceBeatUsedForCompression = (flagByte&0x01) != 0;
reservedBit1 = (flagByte&0x02) != 0;
leadsAllSimultaneouslyRecorded = (flagByte&0x04) != 0;
numberOfSimultaneouslyRecordedLeads = (flagByte&0xf8)>>3;
startingSampleNumbers = new long[numberOfLeads];
endingSampleNumbers = new long[numberOfLeads];
numbersOfSamples = new long[numberOfLeads];
leadNumbers = new int[numberOfLeads];
int lead=0;
while (sectionBytesRemaining > 0) {
startingSampleNumbers[lead] = i.readUnsigned32();
bytesRead+=4;
sectionBytesRemaining-=4;
endingSampleNumbers[lead] = i.readUnsigned32();
bytesRead+=4;
sectionBytesRemaining-=4;
leadNumbers[lead] = i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
numbersOfSamples[lead]=endingSampleNumbers[lead]-startingSampleNumbers[lead]+1;
++lead;
}
if (lead != numberOfLeads) {
System.err.println("Section 3 Number Of Leads specified as "+numberOfLeads+" but encountered "+lead);
}
skipToEndOfSectionIfNotAlreadyThere(i);
return bytesRead;
}
public String toString() {
StringBuffer strbuf = new StringBuffer();
strbuf.append("Number of Leads = "+numberOfLeads+" dec (0x"+Integer.toHexString(numberOfLeads)+")\n");
strbuf.append("Flag byte = "+flagByte+" dec (0x"+Integer.toHexString(flagByte)+")\n");
strbuf.append("\t"+(referenceBeatUsedForCompression ? "Reference Beat Used For Compression" : "Reference Beat Not Used For Compression")+"\n");
strbuf.append("\t"+(reservedBit1 ? "Reserved Bit 1 Set" : "Reserved Bit 1 Reset")+"\n");
strbuf.append("\t"+(leadsAllSimultaneouslyRecorded ? "Leads All Simultaneously Recorded" : "Leads Not All Simultaneously Recorded")+"\n");
strbuf.append("\tNumber of Simultaneously Recorded Leads = "+
numberOfSimultaneouslyRecordedLeads+" dec (0x"+Integer.toHexString(numberOfSimultaneouslyRecordedLeads)+")\n");
strbuf.append("Lead details:\n");
for (int lead=0; lead<numberOfLeads; ++lead) {
strbuf.append("\tLead "+lead+":\n");
strbuf.append("\t\tStartingSampleNumbers = "+startingSampleNumbers[lead]+" dec (0x"+Long.toHexString(startingSampleNumbers[lead])+")\n");
strbuf.append("\t\tEndingSampleNumbers = "+endingSampleNumbers[lead]+" dec (0x"+Long.toHexString(endingSampleNumbers[lead])+")\n");
strbuf.append("\t\tNumber of Samples (computed) = "+numbersOfSamples[lead]+" dec (0x"+Long.toHexString(numbersOfSamples[lead])+")\n");
strbuf.append("\t\tLead Number = "+leadNumbers[lead]+" dec (0x"+Long.toHexString(leadNumbers[lead])+") ");
strbuf.append(getLeadName(leadNumbers[lead])+"\n");
}
return strbuf.toString();
}
public String validate() {
return "";
}
}