Menu

creating SCP file from scratch using SCPForma

Help
2010-05-30
2019-06-17
  • Nobody/Anonymous

    Is it possible to create an SCP-ECG file from scratch (by using an 'external' signal, so not converting from another format) just by filling SCPFormat object fields and properties? What set of information is required (let's say i have only raw signal data, signal properties -sampling rate etc and demographic data)

     
  • MJB van Ettinger

    Required fields:

    Demographics info:
    PatientID
    AcqMachineID
    TimeAcquisition

    Signals info:
    NrLeads (to set the nr of leads)
    RhythmAVM
    RhythmSamplesPerSecond

    Signal info (element of Signals):
    Type
    Rhythm
    RhythmStart
    RhythmEnd

    I hope this will put you in the right direction.

     
  • Nobody/Anonymous

    thank you very much for quick response, that certainly sheds some light
    I have another question: how do I set up Demographics info?
    SCPFormat.Demographics is read only do i have to fill in SCPFormat.Section1 properties instead?

     
  • MJB van Ettinger

    Well easiest is to post the code I use to make my own files:

    // get an empty ECG format file
    IECGFormat format = ECGConverter.Instance.getFormat(ExportFormat);
    if (format != null)
    {
        // five required actions for the demographic info.
        format.Demographics.Init();
        format.Demographics.PatientID = "PatID";
        format.Demographics.LastName = "Test Data"; // this one isn't really required but we aren't just numbers right.
        format.Demographics.TimeAcquisition = DateTime.Now;
        // make an AcquiringDeviceID object
        AcquiringDeviceID acqID = new AcquiringDeviceID(true);
    
        // can also specify your own acquiring device info
        Communication.IO.Tools.BytesTool.writeString("MYDEVI", acqID.ModelDescription, 0, acqID.ModelDescription.Length);
        // set the Acquiring Device ID (required)
        format.Demographics.AcqMachineID = acqID;
        // declare the signal part.
        Signals sigs = new Signals((byte)leadType.Length);
        sigs.RhythmAVM = rhythmAVM;
        sigs.RhythmSamplesPerSecond = rhythmSPS;
    
        for (int i = 0;i < sigs.NrLeads;i++)
        {
            // ignore this part (Making some ECG data)
            short[] rhythm = new short[rhythmSPS * rhythmSecs];     
            for (int j=0;j < rhythm.Length;j++)
            {
                rhythm[j] = (short) ((2000.0 / ((rhythmSPS >> 1) - (j % (rhythmSPS >> 1)))) / rhythmAVM);
                if ((i & 1) != 0)
                    rhythm[j] = (short)(-rhythm[j]);
                if ((i % 3) == 1)
                    rhythm[j] *= 2;
            }
            // end of ignored section
            // very important to assign signal.
            sigs[i] = new Signal();
            sigs[i].Type = leadType[i];
            sigs[i].Rhythm = rhythm;
            sigs[i].RhythmStart = 0;
            sigs[i].RhythmEnd = rhythm.Length-1;
        }
        // store signal to the format.
        if (format.Signals.setSignals(sigs) != 0)
        {
            Console.Error.WriteLine("setSignals failed!");
            return;
        }
        // write the file
        ECGWriter.Write(format, OutputFile, true);
        if (ECGWriter.getLastError() != 0)
        {
            Console.Error.WriteLine("Writing failed: {0}!", ECGWriter.getLastErrorMessage());
            return;
        }
    }
    

    Hope this will help you.

     
  • Nobody/Anonymous

    Hmm actually I see no way of setting up demographics :/ Am I doing something wrong?

     
  • Nobody/Anonymous

    Well MJB that is a huge help for me :) thank you very much for posting this snippet it clarifies a lot

     
  • MJB van Ettinger

    I can't help it my parent gave me three first names. The M stands for: Maarten.

    Perhaps I should add this code to the Sample Apps Forum?

    How did you learn about the C# ECG Toolkit? Did you read my articles for: Code Projects and Computers in Cardiology?

     
  • Nobody/Anonymous

    The more the better :)
    Well I've been looking for a .NET library that can write / read SCP-ECG files, I really appreciate your effort here.

    By the way I think posting this to sample code is a good idea, however I dont understand how Signal objects are assigned to Signals object, I mean the code:

    // very important to assign signal. 
    sigs = new Signal(); 
    sigs.Type = leadType;
     sigs.Rhythm = rhythm; 
    sigs.RhythmStart = 0; 
    sigs.RhythmEnd = rhythm.Length-1;
    

    and few lines above sigs is defined like this:

    Signals sigs = new Signals((byte)leadType.Length);
    

    Here is my test code, that generates an .scp file, but unfortunately for some reason it seems to contain no lead signal data :( (I am doing something wrong probably)

    SCPFormat format = new SCPFormat();
                format.Demographics.Init();
                format.Demographics.PatientID = "PatID";
                format.Demographics.LastName = "Test Data";
                AcquiringDeviceID acqID = new AcquiringDeviceID(true);
                format.Demographics.TimeAcquisition = DateTime.Now; 
                Communication.IO.Tools.BytesTool.writeString("MYDEVI", acqID.ModelDescription, 0, acqID.ModelDescription.Length);
                format.Demographics.AcqMachineID = acqID; 
                Signals signals = new Signals(2);
                signals.NrLeads = 2;
                signals.RhythmAVM = 0.1;
                signals.RhythmSamplesPerSecond = 100;
                List<Signal> sigs = new List<Signal>();
                for (int i = 0; i < signals.NrLeads; i++)
                {
                    short[] rhythm = new short[100000];
                    for (int ii = 0; ii < 100000; ii++)
                    {
                        rhythm[ii] = (short)(Math.Sin(ii) * 10);
                    }
                    var lead = new Signal();
                    
                    lead.Rhythm = rhythm;
                    lead.RhythmStart = 0;
                    lead.RhythmEnd = 99999;
                    sigs.Add(lead);
                }
                sigs[0].Type = LeadType.I;
                sigs[1].Type = LeadType.II;
                signals.SetLeads(sigs.ToArray());
                var res = format.setSignals(signals);
                ECGWriter.Write(format, "2.scp", true);
                res = ECGWriter.getLastError();
                var str = ECGWriter.getLastErrorMessage();
    

    Any hints on that?

     
  • MJB van Ettinger

    Ah my bad :S

    an i between brackets is removed from the post. I replace my i variable with an x.

    // get an empty ECG format file
    IECGFormat format = ECGConverter.Instance.getFormat(ExportFormat);
    if (format != null)
    {
        // five required actions for the demographic info.
        format.Demographics.Init();
        format.Demographics.PatientID = "PatID";
        format.Demographics.LastName = "Test Data";
        format.Demographics.TimeAcquisition = DateTime.Now;
        // make an AcquiringDeviceID object
        AcquiringDeviceID acqID = new AcquiringDeviceID(true);
    
        // can also specify your own acquiring device info
        Communication.IO.Tools.BytesTool.writeString("MYDEVI", acqID.ModelDescription, 0, acqID.ModelDescription.Length);
        // set the Acquiring Device ID (required)
        format.Demographics.AcqMachineID = acqID;
        // declare the signal part.
        Signals sigs = new Signals((byte)leadType.Length);
        sigs.RhythmAVM = rhythmAVM;
        sigs.RhythmSamplesPerSecond = rhythmSPS;
    
        for (int x = 0;x < sigs.NrLeads;x++)
        {
            // ignore this part (Making some ECG data)
            short[] rhythm = new short[rhythmSPS * rhythmSecs];     
            for (int y=0;y < rhythm.Length;y++)
            {
                rhythm[y] = (short) ((2000.0 / ((rhythmSPS >> 1) - (y % (rhythmSPS >> 1)))) / rhythmAVM);
                if ((x & 1) != 0)
                    rhythm[y] = (short)(-rhythm[y]);
                if ((x % 3) == 1)
                    rhythm[y] *= 2;
            }
            // very important to assign signal.
            sigs[x] = new Signal();
            sigs[x].Type = leadType[x];
            sigs[x].Rhythm = rhythm;
            sigs[x].RhythmStart = 0;
            sigs[x].RhythmEnd = rhythm.Length-1;
        }
        // store signal to the format.
        if (format.Signals.setSignals(sigs) != 0)
        {
            Console.Error.WriteLine("setSignals failed!");
            return;
        }
        // write the file
        ECGWriter.Write(format, OutputFile, true);
        if (ECGWriter.getLastError() != 0)
        {
            Console.Error.WriteLine("Writing failed: {0}!", ECGWriter.getLastErrorMessage());
            return;
        }
    }
    
     
  • Ramanpreet Kaur

    Ramanpreet Kaur - 2019-06-14

    I have .atc file and need to convert this json data into SCP-ECG file. How could I write .scp file from custom data, please provide sample code if possible

     
  • MJB van Ettinger

    I think the provided code is pretty clear how to generate an SCP-ECG file, but beware there has to be some consistency between all provided leads (instances of Signal) and you must copy in the right AVM, sample rate (SPS) and samples into each instance of the Signal class.

    If you want me give you more specific support you can provide me with your current code. I'm always willing to take look at a specific issue.

     

Log in to post a comment.