ecgtool.cs
来自「ecg tool kit for medical image retrieval」· CS 代码 · 共 829 行 · 第 1/2 页
CS
829 行
dst = src;
return 0;
}
dst = new short[src.Length][];
// Do resampling for each lead.
for (int loper=0;loper < dst.Length;loper++)
{
if (ResampleLead(src[loper], startsample, nrsamples, srcFreq, dstFreq, out dst[loper]) != 0)
{
dst = null;
return (0x2 << loper);
}
}
return 0;
}
return 1;
}
/// <summary>
/// Function to resample one lead of a signal.
/// </summary>
/// <param name="src">lead of signal to resample</param>
/// <param name="srcFreq">sample rate of signal</param>
/// <param name="dstFreq">destination sample rate</param>
/// <param name="dst">resampled signals</param>
/// <returns>0 on success</returns>
public static int ResampleLead(short[] src, int srcFreq, int dstFreq, out short[] dst)
{
dst = null;
if (src != null)
{
return ResampleLead(src, 0, src.Length, srcFreq, dstFreq, out dst);
}
return 1;
}
/// <summary>
/// Function to resample one lead of a signal.
/// </summary>
/// <param name="src">lead of signal to resample</param>
/// <param name="nrsamples">nr of samples in source</param>
/// <param name="srcFreq">sample rate of signal</param>
/// <param name="dstFreq">destination sample rate</param>
/// <param name="dst">resampled signals</param>
/// <returns>0 on success</returns>
public static int ResampleLead(short[] src, int nrsamples, int srcFreq, int dstFreq, out short[] dst)
{
dst = null;
if (src != null)
{
return ResampleLead(src, 0, src.Length, srcFreq, dstFreq, out dst);
}
return 1;
}
/// <summary>
/// Function to resample one lead of a signal.
/// </summary>
/// <param name="src">lead of signal to resample</param>
/// <param name="startsample">samplenr to start resampleing</param>
/// <param name="nrsamples">nr of samples in source</param>
/// <param name="srcFreq">sample rate of signal</param>
/// <param name="dstFreq">destination sample rate</param>
/// <param name="dst">resampled signals</param>
/// <returns>0 on success</returns>
public static int ResampleLead(short[] src, int startsample, int nrsamples, int srcFreq, int dstFreq, out short[] dst)
{
int n = ((ResampleInterval * srcFreq) / 1000); // n= number of samples for a 20 ms (resample)interval
dst = null;
// Make n a even number and larger then or equal to 2
n>>=1;
if (n<=0)
{n=1;}
n<<=1;
MakeFastTable(n, srcFreq, dstFreq);
if ((src != null)
&& (n > 1)
&& (srcFreq > 0)
&& (dstFreq > 0)
&& (startsample >= 0)
&& (nrsamples > 0)
&& ((startsample + nrsamples) <= src.Length))
{
if (srcFreq == dstFreq)
{
dst = new short[nrsamples];
for (int nLoper=0;nLoper < nrsamples;nLoper++)
dst[nLoper] = src[nLoper + startsample];
return 0;
}
int err = 0;
dst = new short[(nrsamples * dstFreq) / srcFreq + 1];
int tussenFreq = KGV(srcFreq, dstFreq);
int srcAdd = tussenFreq / srcFreq;
int dstAdd = tussenFreq / dstFreq;
int start = (startsample * srcAdd);
int end = (startsample + nrsamples) * srcAdd;
for (int tussenLoper=start;tussenLoper < end;tussenLoper+=dstAdd)
{
// If sample matches precisly a sample of source do no calculations.
if ((tussenLoper % srcAdd) == 0)
{
dst[(tussenLoper - start) / dstAdd] = src[tussenLoper / srcAdd];
}
else
{
// Determine first sample for polynoom.
int first = tussenLoper / srcAdd - (n >> 1);
// determine used N (for n at begin and end of data).
int usedN = n;
// if first is smaller then 0 make N smaller.
if (first < -1)
{
usedN -= ((-1 - first) << 1);
first = -1;
}
// if last is greater or equal then nrsamples make N smaller.
if (first + usedN >= nrsamples)
{
usedN -= (((first + usedN) - nrsamples) << 1);
first = nrsamples - usedN - 1;
}
if (((dstFreq / srcFreq) == 2)
&& ((dstFreq % srcFreq) == 0))
{
int p = ((usedN >> 1)-1);
double result = 0;
for (int loper=0;loper < usedN;loper++)
{
result += (src[first+1+loper] * Fast[p][loper]);
}
dst[(tussenLoper - start) / dstAdd] = (short) result;
}
else
{
// Allocate two arrays for calculations
double[] c = new double[usedN+1];
double[] d = new double[usedN+1];
double den = 0;
int ns = 1;
int dif = Math.Abs(tussenLoper - ((first + 1) * srcAdd));
// Fill arrays with source samples.
for (int loper=1;loper <= usedN;loper++)
{
int dift;
if ((dift = Math.Abs(tussenLoper - ((first + loper) * srcAdd))) < dif)
{
ns = loper;
dif = dift;
}
c[loper] = src[first + loper];
d[loper] = src[first + loper];
}
// The initial approximation
double y = src[first + ns--];
for (int loper1=1;loper1 < usedN;loper1++)
{
for (int loper2=1;loper2 <= (usedN - loper1);loper2++)
{
int ho = ((first + loper2) * srcAdd) - tussenLoper;
int hp = ((first + loper2 + loper1) * srcAdd) - tussenLoper;
double w = c[loper2 + 1] - d[loper2];
if ((den = ho - hp) == 0)
{
// Error when no difference (dividing by zero is impossible)
err |= 0x2;
}
den = w / den;
d[loper2]= hp * den;
c[loper2]= ho * den;
}
// Change approxiamation.
y += ((ns << 1) < (usedN - loper1) ? c[ns + 1] : d[ns--]);
}
// set value destination with approxiamation.
dst[(tussenLoper - start) / dstAdd] = (short) y;
}
}
}
return err;
}
return 1;
}
/// <summary>
/// Make the fasttable.
/// </summary>
/// <param name="n">nr of samples resambles 20ms</param>
/// <param name="srcFreq">sample rate of signal</param>
/// <param name="dstFreq">destination sample rate</param>
private static void MakeFastTable(int n, int srcFreq, int dstFreq)
{
// Make a table when fast calculation is possible
if (((dstFreq / srcFreq) == 2)
&& ((dstFreq % srcFreq) == 0))
{
// Only make a new table if needed.
if ((Fast == null)
|| (Fast.Length < (n >> 1)))
{
double[][] temp = Fast;
Fast = new double[n >> 1][];
for (int x=0;x < Fast.Length;x++)
{
// If fast table previously available, don't calculate again.
if ((temp != null)
&& (temp.Length > x))
{
Fast[x] = temp[x];
}
else
{
Fast[x] = new double[(x+1) << 1];
for (int y=0;y < Fast[x].Length;y++)
{
Fast[x][y] = 1;
for (int z=0, c=0;z < Fast[x].Length-1;z++, c+=2)
{
if ((y << 1) == c)
{c += 2;}
Fast[x][y] *= (double)(((x<<1)+1) - c) / (double)((y << 1) - c);
}
}
}
}
}
}
}
/// <summary>
/// Function to set an other multiplier (if this function is improperly used data will be lost).
/// </summary>
/// <param name="src">signal to change multiplier</param>
/// <param name="srcmulti">orignal multiplier</param>
/// <param name="dstmulti">preferred multiplier</param>
/// <returns>0 on success</returns>
public static int ChangeMultiplier(short[][] src, double srcmulti, double dstmulti)
{
if ((src != null)
&& (srcmulti == dstmulti))
{
return 0;
}
else if ((src != null)
&& (srcmulti > 0)
&& (dstmulti > 0))
{
for (int loper=0;loper < src.Length;loper++)
{
if (ChangeMultiplier(src[loper], srcmulti, dstmulti) != 0)
{
return (0x2 << loper);
}
}
return 0;
}
return 1;
}
/// <summary>
/// Function to set an other multiplier (if this function is improperly used data will be lost).
/// </summary>
/// <param name="src">Lead to change multiplier</param>
/// <param name="srcmulti">orignal multiplier</param>
/// <param name="dstmulti">preferred multiplier</param>
/// <returns>0 on success</returns>
public static int ChangeMultiplier(short[] src, double srcmulti, double dstmulti)
{
if ((src != null)
&& (srcmulti == dstmulti))
{
return 0;
}
else if ((src != null)
&& (srcmulti > 0)
&& (dstmulti > 0))
{
for (int loper=0;loper < src.Length;loper++)
{
src[loper] = (short) ((src[loper] * srcmulti) / dstmulti);
}
return 0;
}
return 1;
}
/// <summary>
/// Function to copy a signal.
/// </summary>
/// <param name="src">source array of signal</param>
/// <param name="src_offset">offset in source array to start copy at</param>
/// <param name="dst">destination array for signal</param>
/// <param name="dst_offset">offset in destination array to start copy at</param>
/// <param name="len">length of the copy</param>
/// <returns>0 if succesfull or 1 if invalid arguments</returns>
public static int CopySignal(short[] src, int src_offset, short[] dst, int dst_offset, int len)
{
if ((src != null)
&& (dst != null)
&& (src_offset >= 0)
&& (dst_offset >= 0)
&& (len > 0)
&& ((dst_offset + len) <= dst.Length))
{
if ((src_offset + len) > src.Length)
len = src.Length - src_offset;
for (int i=0;i < len;i++)
dst[dst_offset + i] = src[src_offset + i];
return 0;
}
return 1;
}
/// <summary>
/// Function to determine the "grootste gemene deler"
/// </summary>
/// <param name="x1">value 1</param>
/// <param name="x2">value 2</param>
/// <returns>"grootste gemene deler"</returns>
private static int GGD(int x1, int x2)
{
if ((x1 == 0)
|| (x2 == 0))
{
return 0;
}
if (x1 >= x2)
{
if ((x1 % x2) == 0)
{
return x2;
}
return GGD(x2, x1 % x2);
}
return GGD(x2, x1);
}
/// <summary>
/// Function to determine the "kleinst gemene veelvoud"
/// </summary>
/// <param name="x1">value 1</param>
/// <param name="x2">value 2</param>
/// <returns>"kleinst gemene veelvoud"</returns>
private static int KGV(int x1, int x2)
{
int ggd = GGD(x1, x2);
return (ggd == 0 ? 0 : (x1 * x2) / ggd);
}
/// <summary>
/// Function to anonymous an instance of IDemographics.
/// </summary>
/// <param name="demo">instance to anonymous</param>
/// <param name="type">char to use</param>
public static void Anonymous(ECGDemographics.IDemographic demo, char type)
{
string temp = demo.LastName;
if (temp != null)
demo.LastName = new string(type, temp.Length);
temp = demo.FirstName;
if (temp != null)
demo.FirstName = new string(type, temp.Length);
temp = demo.PatientID;
if (temp != null)
demo.PatientID = new string(type, temp.Length);
temp = demo.SecondLastName;
if (temp != null)
demo.SecondLastName = new string(type, temp.Length);
temp = demo.PrefixName;
if (temp != null)
demo.PrefixName = new string(type, temp.Length);
temp = demo.SuffixName;
if (temp != null)
demo.SuffixName = new string(type, temp.Length);
ECGDemographics.Date date = demo.PatientBirthDate;
if (date != null)
{
date.Day = 1;
date.Month = 1;
demo.PatientBirthDate = date;
}
temp = demo.SequenceNr;
if (temp != null)
demo.SequenceNr = "1";
}
private ECGTool(){}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?