⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scp_formatter.cpp

📁 BIOSIG is an open source software library for biomedical signal processing. Library works well with
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

int16_t cSCP_Formatter::GetLastConfirmingPhys(char* LCPhys)
{
	if (LCPhys == NULL)
		return (-1);

	LCPhys[0] = '\0';

	if (S1I == NULL)
		return (-2);

	strncpy(LCPhys, S1I->szLCPhys, 63);
	LCPhys[63] = '\0';

	return (0);
}

int16_t cSCP_Formatter::SetStatCode(int16_t StatCode)
{
	if ((StatCode < 0) || (StatCode > 10))	// 0 = routine; 1 = lowest emergency level,
											// .........., 10 = highest emergency level
		return (-1);

	if (S1I == NULL) {
		S1I = new cSection1_Info();
	}

	if (S1I == NULL)
		return (-2);

	S1I->bStatCode = (uint8_t) StatCode;

	return (0);
}

int16_t cSCP_Formatter::GetStatCode(int16_t* StatCode)
{
	if (StatCode == NULL)
		return (-1);

	*StatCode = 0;

	if (S1I == NULL)
		return (-2);

	*StatCode = S1I->bStatCode;

	return (0);
}

int16_t cSCP_Formatter::SetDateOfAcquisition(int16_t dd, int16_t mm, int16_t yyyy)
{
	if ((dd < 1) || (dd > 31))
		return (-1);
	if ((mm < 1) || (mm > 12))
		return (-1);

// Inserted further checks on the date of birth correctness
	// April, June, September and November have 30 days
	if ((mm == 4) || (mm == 6) || (mm == 9) || (mm == 11))
		if (dd == 31)
			return (-1);
	// February cannot have more than 29 days
	if (mm == 2)
		if (dd > 29)
			return (-1);
	// Check on leap years
	if ((yyyy % 4) == 0) {
		if (((yyyy % 100) == 0) && ((yyyy % 400) != 0)) {
			// Not leap
			if (dd == 29)
				return (-1);
		}
		else {
			// Leap (do nothing)
		}
	}

	if (S1I == NULL) {
		S1I = new cSection1_Info();
	}

	if (S1I == NULL)
		return (-2);

	S1I->DOA.dd = (uint8_t) ((0x00FF) & dd);
	S1I->DOA.mm = (uint8_t) ((0x00FF) & mm);
	S1I->DOA.yyyy = yyyy;

	return (0);
}

int16_t cSCP_Formatter::GetDateOfAcquisition(int16_t* dd, int16_t* mm, int16_t* yyyy)
{
	if ((dd == NULL) || (mm == NULL) || (yyyy == NULL)) {
		if (dd != NULL)
			*dd = 0;
		if (mm != NULL)
			*mm = 0;
		if (yyyy != NULL)
			*yyyy = 0;
		return (-1);
	}

	*dd = 0;
	*mm = 0;
	*yyyy = 0;

	if (S1I == NULL)
		return (-2);

	*dd = S1I->DOA.dd;
	*mm = S1I->DOA.mm;
	*yyyy = S1I->DOA.yyyy;

	return (0);
}

int16_t cSCP_Formatter::SetTimeOfAcquisition(int16_t hh, int16_t mm, int16_t ss)
{
	if ((hh < 0) || (hh > 23))
		return (-1);
	if ((mm < 0) || (mm > 59))
		return (-1);
	if ((ss < 0) || (ss > 59))
		return (-1);

// Eventually insert further checks on the time of acquisition correctness

	if (S1I == NULL) {
		S1I = new cSection1_Info();
	}

	if (S1I == NULL)
		return (-2);

	S1I->TOA.hh = (uint8_t) ((0x00FF) & hh);
	S1I->TOA.mm = (uint8_t) ((0x00FF) & mm);
	S1I->TOA.ss = (uint8_t) ((0x00FF) & ss);

	return (0);
}

int16_t cSCP_Formatter::GetTimeOfAcquisition(int16_t* hh, int16_t* mm, int16_t* ss)
{
	if ((hh == NULL) || (mm == NULL) || (ss == NULL)) {
		if (hh != NULL)
			*hh = 0;
		if (mm != NULL)
			*mm = 0;
		if (ss != NULL)
			*ss = 0;
		return (-1);
	}

	*hh = 0;
	*mm = 0;
	*ss = 0;

	if (S1I == NULL)
		return (-2);

	*hh = S1I->TOA.hh;
	*mm = S1I->TOA.mm;
	*ss = S1I->TOA.ss;

	return (0);
}

int16_t cSCP_Formatter::SetSequenceNumber(int8_t* SeqNum)
{
	if (SeqNum == NULL)
		return (-1);

	if (S1I == NULL) {
		S1I = new cSection1_Info();
	}

	if (S1I == NULL)
		return (-2);

	memcpy(S1I->szSeqNum, SeqNum, 11);
	S1I->szSeqNum[11] = '\0';

	if (strlen((char*)SeqNum) > 11)
		return (-3);
	else
		return (0);
}

int16_t cSCP_Formatter::GetSequenceNumber(int8_t* SeqNum)
{
	if (SeqNum == NULL)
		return (-1);

	SeqNum[0] = '\0';

	if (S1I == NULL)
		return (-2);

	memcpy(SeqNum, S1I->szSeqNum, 11);
	SeqNum[11] = '\0';

	return (0);
}

int16_t cSCP_Formatter::SetTimeZone(int16_t TimeZone)
{
// Insert some tests to check the correctness of the input parameter

	if (S1I == NULL) {
		S1I = new cSection1_Info();
	}

	if (S1I == NULL)
		return (-2);

	S1I->wDateTimeZoneOffset = TimeZone;

	return (0);
}

int16_t cSCP_Formatter::GetTimeZone(int16_t* TimeZone)
{
	if (TimeZone == NULL)
		return (-1);

	*TimeZone = 0;

	if (S1I == NULL)
		return (-2);

	*TimeZone = S1I->wDateTimeZoneOffset;

	return (0);
}

int16_t cSCP_Formatter::LoadXMLInfo(HDRTYPE* XMLaECGParsedData)
{
	int16_t val1, val2;
	uint16_t i;
//	uint16_t k, j;

	// Name should be provided by the XML parser in terms of first name, last name, second last name
	strncpy(S1I->szFirstName, XMLaECGParsedData->Patient.Name, min(strlen(XMLaECGParsedData->Patient.Name),63));
	S1I->szFirstName[63] = '\0';
	strncpy(S1I->szLastName, XMLaECGParsedData->Patient.Name, min(strlen(XMLaECGParsedData->Patient.Name),63));
	S1I->szLastName[63] = '\0';
	strncpy(S1I->szSecondLastName, XMLaECGParsedData->Patient.Name, min(strlen(XMLaECGParsedData->Patient.Name),63));
	S1I->szSecondLastName[63] = '\0';

	if (strlen(XMLaECGParsedData->Patient.Id) != 0) { // In case len = 0 the PatID field will be written with "UNKNOWN"
		strncpy(S1I->szPatientID, XMLaECGParsedData->Patient.Id, min(strlen(XMLaECGParsedData->Patient.Id),63));
		S1I->szPatientID[63] = '\0';
	}

	time_t Birthday = gdf_time2t_time(XMLaECGParsedData->Patient.Birthday);
	tm* Birthday_tm = gmtime(&Birthday);

	S1I->DOB.dd = (uint8_t) Birthday_tm->tm_mday;
	S1I->DOB.mm = (uint8_t) Birthday_tm->tm_mon + 1;
	S1I->DOB.yyyy = (uint8_t) Birthday_tm->tm_year + 1900;

	S1I->wHeight = (uint16_t) XMLaECGParsedData->Patient.Height;
	//S1I->bHeightUnit is always cm

	S1I->wWeight = (uint16_t) XMLaECGParsedData->Patient.Weight;
	//S1I->bWeightUnit is always Kg

	if(XMLaECGParsedData->Patient.Sex == 0)
		S1I->bSex = 0;	// Not Known
	else if (XMLaECGParsedData->Patient.Sex == 1)
		S1I->bSex = 1;	// Male
	else if (XMLaECGParsedData->Patient.Sex == 2)
		S1I->bSex = 2;	// Female
	else
		S1I->bSex = 9;	// Not specified

	val1 = (uint16_t) XMLaECGParsedData->aECG->systolicBloodPressure;
	val2 = (uint16_t) XMLaECGParsedData->aECG->diastolicBloodPressure;

	if (val1 < val2) {
		S1I->wDBP = val1;
		S1I->wSBP = val2;
	}
	else {
		S1I->wDBP = val2;
		S1I->wSBP = val1;
	}

	// Info not provided by XML aECG
	//S1I->wInstNum = (uint16_t) atoi(XMLaECGParsedData->szRecAqrInstID);
	//S1I->wDeptNum = (uint16_t) atoi(XMLaECGParsedData->szRecAqrDeptID);
	//strncpy(S1I->szAnalProgRevNum, XMLaECGParsedData->szRecAnaProgRev, 24);
	//S1I->szAnalProgRevNum[24] = '\0';
	//strncpy(S1I->szAcqDevSystSW, XMLaECGParsedData->szRecAqrDevRev, 24);
	//S1I->szAcqDevSystSW[24] = '\0';

	// Info not provided by XML aECG
	//strncpy(S1I->szRefPhys, XMLaECGParsedData->ReferringPhys, 63);
	//S1I->szRefPhys[63] = '\0';
	
	strncpy(S1I->szTechnician, XMLaECGParsedData->ID.Technician, min(strlen(XMLaECGParsedData->ID.Technician),63));
	S1I->szTechnician[63] = '\0';

	// Info not provided by XML aECG
	//S1I->wBaseLineFilter = XMLaECGParsedData->BaseLineFilter;
	//S1I->bFilterBitMap = (uint8_t) XMLaECGParsedData->FilterBitMap;
	
	// Info not provided by XML aECG
	//S1I->bStatCode = (uint8_t) XMLaECGParsedData->StatCode;
	//if (S1I->bStatCode > 10)
	//	S1I->bStatCode = 0;

	time_t AcquisitionDT = gdf_time2t_time(XMLaECGParsedData->T0);
	tm* AcquisitionDT_tm = gmtime(&AcquisitionDT);

	S1I->DOA.dd = (uint8_t) AcquisitionDT_tm->tm_mday;
	S1I->DOA.mm = (uint8_t) AcquisitionDT_tm->tm_mon + 1;
	S1I->DOA.yyyy = (int16_t) AcquisitionDT_tm->tm_year + 1900;

	S1I->TOA.hh = (uint8_t) AcquisitionDT_tm->tm_hour;
	S1I->TOA.mm = (uint8_t) AcquisitionDT_tm->tm_min;
	S1I->TOA.ss = (uint8_t) AcquisitionDT_tm->tm_sec;

	ESI->dwEndSampleR = XMLaECGParsedData->SPR;
	// LSB is assumed to be the same over all the stored leads
	ESI->wAmplR = (uint16_t) XMLaECGParsedData->CHANNEL[0].Cal;
	ESI->wIntvR = (uint16_t) XMLaECGParsedData->SampleRate;
	// No reference beat seems to be available in XML aECG
	ESI->dwEndSampleA = 1;
	// LSB is assumed to be 1 uV
	ESI->wAmplA = 1;
	ESI->wIntvA = (uint16_t) XMLaECGParsedData->SampleRate;

	// max 15 leads are allowed
	if(XMLaECGParsedData->NS > 15)
		return (-1);

	ESI->bNumLead = (uint8_t) XMLaECGParsedData->NS;
// Situations with number of leads simultaneouly recorded != total number of leads are not supported
	ESI->bNumLeadSimultRecord = (uint8_t) XMLaECGParsedData->NS;

	// Max 15 leads are supported
	// Same lead codes are used between XML aECG and SCP-ECG ver. 2.0. This is not strictly correct because
	// in SCP 2.0 only codes till 78 are the same, while from 86 on the codes are not defined, but we can
	// assume the use of the same codes like manufacturer dependent codes
	for (i = 0; i < ESI->bNumLead; i++) {
		ESI->LeadR_codes[i] = *XMLaECGParsedData->CHANNEL[i].Label;
	}
	for (i = 0; i < ESI->bNumLead; i++) {		ESI->LeadR[i] = XMLaECGParsedData->data.block + i*XMLaECGParsedData->data.size[0];
	}
	// No reference beat seems to be available in XML aECG
	for (i = 0; i < ESI->bNumLead; i++) {
		ESI->LeadA_codes[i] = 0;
	}
	for (i = 0; i < ESI->bNumLead; i++) {
		ESI->LeadA[i] = NULL;
	}

	// No global measurements, lead specific measurements or diagnosis are provided
	//ESI->wPOn = XMLaECGParsedData->GlobalMeas.P_onset;
	//ESI->wPOff = XMLaECGParsedData->GlobalMeas.P_end;
	//ESI->wQRSOn = XMLaECGParsedData->GlobalMeas.QRS_onset;
	//ESI->wQRSOff = XMLaECGParsedData->GlobalMeas.QRS_end;
	//ESI->wTOff = XMLaECGParsedData->GlobalMeas.T_end;

	//ESI->wAverFiducial = XMLaECGParsedData->GlobalMeas.QRS_onset;	// QRSOn
	//if (ESI->wAverFiducial == 0)
	//	ESI->wAverFiducial = 100;

	//ESI->wNoOfQRS = XMLaECGParsedData->GlobalMeas.Num_Cpxs;
	//ESI->pwTblQRSType = (uint16_t*) &XMLaECGParsedData->GlobalMeas.QRS_type;
	//ESI->pwTblQRSOn = (uint32_t*) &XMLaECGParsedData->GlobalMeas.QRS_start_refbeat_sub;
	//ESI->pwTblQRSOff = (uint32_t*) &XMLaECGParsedData->GlobalMeas.QRS_end_refbeat_sub;
	
	//ESI->szInterpText = XMLaECGParsedData->MeansMorfologia;

	////ESI->wGlobMeas[0] = XMLaECGParsedData->GlobalMeas.HR;
	//ESI->wGlobMeas[1] = XMLaECGParsedData->GlobalMeas.RR_median;
	//ESI->wGlobMeas[2] = XMLaECGParsedData->GlobalMeas.PQ_intv;
	////ESI->wGlobMeas[3] = XMLaECGParsedData->GlobalMeas.PP;
	//ESI->wGlobMeas[4] = XMLaECGParsedData->GlobalMeas.QRS_dur;
	//ESI->wGlobMeas[5] = XMLaECGParsedData->GlobalMeas.QT_intv;
	//ESI->wGlobMeas[6] = XMLaECGParsedData->GlobalMeas.QTc_intv;
	//ESI->wGlobMeas[7] = XMLaECGParsedData->GlobalMeas.P_axis;
	//ESI->wGlobMeas[8] = XMLaECGParsedData->GlobalMeas.QRS_axis;
	//ESI->wGlobMeas[9] = XMLaECGParsedData->GlobalMeas.STT_axis;

	//for (k = 0; k < ESI->bNumLead; i++) {
	//	for (j = 0; j < 31; j++) {
	//		ESI->wLeadMeas[k][j] = ((int16_t*) &XMLaECGParsedData->LeadMeas[k])[j * 2];
	//	}
	//}

	return (0);
}

bool cSCP_Formatter::CreateSCPFileHeaderDraft()
{
	FileHead.crc = 0;			// Temporary
	FileHead.len = 0;			// Temporary

	return (true);
}

bool cSCP_Formatter::CreateSCPSection0Draft()
{
	if (S1I == NULL)
		return (false);

// Create the header
	Sect0.shead.crc = 0;		// Temporary
	Sect0.shead.sectid = 0;
	Sect0.shead.len = 136;		// 16 bytes of header and 12 rows of 10 bytes each
	Sect0.shead.sectver = S1I->bSCPECGProtRevNum;
	Sect0.shead.protver = S1I->bSCPECGProtRevNum;
	Sect0.shead.SCPres[0] = 'S';
	Sect0.shead.SCPres[1] = 'C';
	Sect0.shead.SCPres[2] = 'P';
	Sect0.shead.SCPres[3] = 'E';
	Sect0.shead.SCPres[4] = 'C';
	Sect0.shead.SCPres[5] = 'G';

// Create all the rows
	Sect0.sect_0.sectid = 0;
	Sect0.sect_0.sectlen = 136;
	Sect0.sect_0.index = 7;
	Sect0.sect_1.sectid = 1;
	Sect0.sect_1.sectlen = 0;	// Temporary
	Sect0.sect_1.index = 143;
	Sect0.sect_2.sectid = 2;
	Sect0.sect_2.sectlen = 0;
	Sect0.sect_2.index = 0;
	Sect0.sect_3.sectid = 3;
	Sect0.sect_3.sectlen = 0;	// Temporary
	Sect0.sect_3.index = 0;		// Temporary
	Sect0.sect_4.sectid = 4;
	Sect0.sect_4.sectlen = 0;	
	Sect0.sect_4.index = 0;		
	Sect0.sect_5.sectid = 5;
	Sect0.sect_5.sectlen = 0;	
	Sect0.sect_5.index = 0;		
	Sect0.sect_6.sectid = 6;
	Sect0.sect_6.sectlen = 0;	// Temporary
	Sect0.sect_6.index = 0;		// Temporary
	Sect0.sect_7.sectid = 7;
	Sect0.sect_7.sectlen = 0;	
	Sect0.sect_7.index = 0;		
	Sect0.sect_8.sectid = 8;
	Sect0.sect_8.sectlen = 0;	
	Sect0.sect_8.index = 0;		
	Sect0.sect_9.sectid = 9;
	Sect0.sect_9.sectlen = 0;
	Sect0.sect_9.index = 0;
	Sect0.sect_10.sectid = 10;
	Sect0.sect_10.sectlen = 0;	
	Sect0.sect_10.index = 0;	
	Sect0.sect_11.sectid = 11;
	Sect0.sect_11.sectlen = 0;
	Sect0.sect_11.index = 0;

// Store the length of Section1
	lenSect0 = Sect0.shead.len;

	return (true);
}

bool cSCP_Formatter::CreateSCPSection1()
{
	SCPSECT_HEAD	Sect1Head;
	TAG				tg;
	uint32_t		len1;
	uint32_t		lenTmp;
	uint16_t		crc;
	uint8_t			bUnit;
	uint8_t			bBufTmp[256];

	if (S1I == NULL)
		return (false);

// Create the header
	Sect1Head.crc = 0;				// Temporary
	Sect1Head.sectid = 1;
	Sect1Head.len = 0;				// Temporary
	Sect1Head.sectver = S1I->bSCPECGProtRevNum;
	Sect1Head.protver = S1I->bSCPECGProtRevNum;
	Sect1Head.SCPres[0] = '\0';
	Sect1Head.SCPres[1] = '\0';
	Sect1Head.SCPres[2] = '\0';
	Sect1Head.SCPres[3] = '\0';
	Sect1Head.SCPres[4] = '\0';
	Sect1Head.SCPres[5] = '\0';

	memcpy(Sect1, (int8_t*) &Sect1Head, 16);
	len1 = 16;

// Create all the tags

// Tag 0 (max len = 64)
	tg.id = 0;
	tg.len = strlen(S1I->szLastName) + 1;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], S1I->szLastName, tg.len);
	len1 += tg.len;

// Tag 1 (max len = 64)
	tg.id = 1;
	tg.len = strlen(S1I->szFirstName) + 1;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], S1I->szFirstName, tg.len);
	len1 += tg.len;

// Tag 2 (max len = 64)
	tg.id = 2;
	tg.len = strlen(S1I->szPatientID) + 1;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], S1I->szPatientID, tg.len);
	len1 += tg.len;

// Tag 3 (max len = 64)
	tg.id = 3;
	tg.len = strlen(S1I->szSecondLastName) + 1;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], S1I->szSecondLastName, tg.len);
	len1 += tg.len;

// Tag 5 (len = 4)
	tg.id = 5;
	tg.len = 4;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], (int8_t*)(&S1I->DOB.yyyy), 2);
	len1 += 2;
	memcpy(&Sect1[len1], (int8_t*)(&S1I->DOB.mm), 1);
	len1 += 1;
	memcpy(&Sect1[len1], (int8_t*)(&S1I->DOB.dd), 1);
	len1 += 1;

// Tag 6 (len = 3)
	tg.id = 6;
	tg.len = 3;
	memcpy(&Sect1[len1], (int8_t*) &tg, 3);
	len1 += 3;
	memcpy(&Sect1[len1], (int8_t*)(&S1I->wHeight), 2);
	len1 += 2;
	if (S1I->wHeight == 0)
		bUnit = 0;
	else
		bUnit = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -