Example #1
0
File: mach5.c Project: h31nr1ch/SOP
badsyntax() {

	serror("bad operands");
}
Example #2
0
void mexFunction(
    int           nlhs,           /* number of expected outputs */
    mxArray       *plhs[],        /* array of pointers to output arguments */
    int           nrhs,           /* number of inputs */
    const mxArray *prhs[]         /* array of pointers to input arguments */
)

{
	int k,k1;
	const mxArray	*arg;
	mxArray		*HDR;
	HDRTYPE		*hdr;
	CHANNEL_TYPE*	cp; 
	size_t 		count;
	time_t 		T0;
	char 		*FileName=NULL;  
	int 		status; 
	int		CHAN = 0;
	int		TARGETSEGMENT = 1; 
	double		*ChanList=NULL;
	int		NS = -1;
	char		FlagOverflowDetection = 1, FlagUCAL = 0;
	char		FLAG_CNT32 = 0;
	int		argSweepSel = -1;
	
#ifdef CHOLMOD_H
	cholmod_sparse RR,*rr=NULL;
	double dummy;
#endif 

// ToDO: output single data 
//	mxClassId	FlagMXclass=mxDOUBLE_CLASS;
	

	if (nrhs<1) {
#ifdef mexSOPEN
		mexPrintf("   Usage of mexSOPEN:\n");
		mexPrintf("\tHDR = mexSOPEN(f)\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("   Output:\n\tHDR\theader structure\n\n");
#else
		mexPrintf("   Usage of mexSLOAD:\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f)\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan)\n\t\tchan must be sorted in ascending order\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,ReRef)\n\t\treref is a (sparse) matrix for rerefencing\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'...')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'CNT32')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OVERFLOWDETECTION:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:ON')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'UCAL:OFF')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'OUTPUT:SINGLE')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'TARGETSEGMENT:<N>')\n");
		mexPrintf("\t[s,HDR]=mexSLOAD(f,chan,'SWEEP',[NE, NG, NS])\n");
		mexPrintf("   Input:\n\tf\tfilename\n");
		mexPrintf("\tchan\tlist of selected channels; 0=all channels [default]\n");
		mexPrintf("\tCNT32: needed to read 32bit CNT files \n");
		mexPrintf("\tUCAL\tON: do not calibrate data; default=OFF\n");
//		mexPrintf("\tOUTPUT\tSINGLE: single precision; default='double'\n");
		mexPrintf("\tOVERFLOWDETECTION\tdefault = ON\n\t\tON: values outside dynamic range are not-a-number (NaN)\n");
		mexPrintf("\tTARGETSEGMENT:<N>\n\t\tselect segment <N> in multisegment files (like Nihon-Khoden), default=1\n\t\tIt has no effect for other data formats.\n");
		mexPrintf("\t[NE, NG, NS] are the number of the experiment, the series and the sweep, resp. for sweep selection in HEKA/PatchMaster files. (0 indicates all)\n");
		mexPrintf("\t\t examples: [1,2,3] the 3rd sweep from the 2nd series of experiment 1; [1,3,0] selects all sweeps from experiment=1, series=3. \n\n");
		mexPrintf("   Output:\n\ts\tsignal data, each column is one channel\n");
		mexPrintf("\tHDR\theader structure\n\n");
#endif
		return; 
	}

/*
 	improve checks for input arguments
*/
	/* process input arguments */
	for (k = 0; k < nrhs; k++) {	
		arg = prhs[k];
		if (mxIsEmpty(arg) && (k>0)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] Empty\n",k);
#endif
		}
		else if ((k==0) && mxIsCell(arg) && mxGetNumberOfElements(arg)==1 && mxGetCell(arg,0) && mxIsChar(mxGetCell(arg,0))) {
			FileName = mxArrayToString(mxGetCell(arg,0));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsCell\n",k);
#endif
		}
		else if ((k==0) && mxIsStruct(arg)) {
			FileName = mxArrayToString(mxGetField(prhs[k],0,"FileName"));
#ifdef DEBUG		
			mexPrintf("arg[%i] IsStruct\n",k);
#endif
		}
#ifdef CHOLMOD_H
		else if ((k==1) && mxIsSparse(arg)) {
			rr = sputil_get_sparse(arg,&RR,&dummy,0);
		}
#endif 
		else if ((k==1) && mxIsNumeric(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i] IsNumeric\n",k);
#endif
			ChanList = (double*)mxGetData(prhs[k]);
			NS = mxGetNumberOfElements(prhs[k]);
		}	
		else if (mxIsChar(arg)) {
#ifdef DEBUG		
			mexPrintf("arg[%i]=%s \n",k,mxArrayToString(prhs[k]));
#endif
			if (k==0)			
				FileName = mxArrayToString(prhs[k]);
			else if (!strcmp(mxArrayToString(prhs[k]), "CNT32"))
				FLAG_CNT32 = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:ON"))
				FlagOverflowDetection = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "OVERFLOWDETECTION:OFF"))
				FlagOverflowDetection = 0;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:ON")) 
				FlagUCAL = 1;
			else if (!strcmp(mxArrayToString(prhs[k]), "UCAL:OFF"))
				FlagUCAL = 0;
//			else if (!strcmp(mxArrayToString(prhs[k]),"OUTPUT:SINGLE"))
//				FlagMXclass = mxSINGLE_CLASS;
			else if (!strncmp(mxArrayToString(prhs[k]),"TARGETSEGMENT:",14))
				TARGETSEGMENT = atoi(mxArrayToString(prhs[k])+14);
			else if (!strcmpi(mxArrayToString(prhs[k]), "SWEEP") && (prhs[k+1] != NULL) && mxIsNumeric(prhs[k+1]))
				argSweepSel = ++k;
		}
		else {
#ifndef mexSOPEN
			mexPrintf("mexSLOAD: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSLOAD failes because of unknown parameter\n");	
#else
			mexPrintf("mexSOPEN: argument #%i is invalid.",k+1);	
			mexErrMsgTxt("mexSOPEN fails because of unknown parameter\n");	
#endif
		}
	}

	if (VERBOSE_LEVEL>7) 
		mexPrintf("110: input arguments checked\n");

	hdr = constructHDR(0,0);
	hdr->FLAG.OVERFLOWDETECTION = FlagOverflowDetection; 
	hdr->FLAG.UCAL = FlagUCAL;
	hdr->FLAG.CNT32 = FLAG_CNT32;
#ifdef CHOLMOD_H
	hdr->FLAG.ROW_BASED_CHANNELS = (rr!=NULL); 
#else 	
	hdr->FLAG.ROW_BASED_CHANNELS = 0; 
#endif 
	hdr->FLAG.TARGETSEGMENT = TARGETSEGMENT;

	// sweep selection for Heka format 
	if (argSweepSel>0) { 				
		double *SZ     = (double*) mxGetData(prhs[argSweepSel]);
		k = 0;
		while (k < mxGetNumberOfElements(prhs[argSweepSel]) && k < 5) { 
			hdr->AS.SegSel[k] = (uint32_t)SZ[k];
			k++;
		}
	}

	if (VERBOSE_LEVEL>7) 
		mexPrintf("120: going to sopen\n");

	hdr = sopen(FileName, "r", hdr);
/*
#ifdef WITH_PDP 
	if (B4C_ERRNUM) {
		B4C_ERRNUM = 0;
		sopen_pdp_read(hdr);
	}	
#endif
*/
	if (VERBOSE_LEVEL>7) 
		mexPrintf("121: sopen done\n");

	if ((status=serror())) {

		const char* fields[]={"TYPE","VERSION","FileName","FLAG","ErrNum","ErrMsg"};
		HDR = mxCreateStructMatrix(1, 1, 6, fields);
		mxSetField(HDR,0,"FileName",mxCreateString(hdr->FileName));
		mxArray *errnum = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
		*(uint8_t*)mxGetData(errnum) = (uint8_t)status;
		mxSetField(HDR,0,"ErrNum",errnum);
		
#ifdef HAVE_OCTAVE
		// handle bug in octave: mxCreateString(NULL) causes segmentation fault
		// Octave 3.2.3 causes a seg-fault in mxCreateString(NULL)
		 
		{
		const char *p = GetFileTypeString(hdr->TYPE);
		if (p) mxSetField(HDR,0,"TYPE",mxCreateString(p));
		}
#else
		mxSetField(HDR,0,"TYPE",mxCreateString(GetFileTypeString(hdr->TYPE)));
#endif
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));

		char msg[1024]; 
		if (status==B4C_CANNOT_OPEN_FILE)
			sprintf(msg,"Error mexSLOAD: file %s not found.\n",FileName);
		else if (status==B4C_FORMAT_UNKNOWN)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not known.\n",FileName,GetFileTypeString(hdr->TYPE));
		else if (status==B4C_FORMAT_UNSUPPORTED)
			sprintf(msg,"Error mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", FileName, GetFileTypeString(hdr->TYPE), B4C_ERRMSG);
		else 	
			sprintf(msg,"Error %i mexSLOAD: Cannot open file %s - format %s not supported [%s].\n", status, FileName, GetFileTypeString(hdr->TYPE), B4C_ERRMSG);
			
		mxSetField(HDR,0,"ErrMsg",mxCreateString(msg));

	if (VERBOSE_LEVEL>7) 
		mexPrintf("737: abort mexSLOAD - sopen failed\n");


		destructHDR(hdr);

	if (VERBOSE_LEVEL>7) 
		mexPrintf("757: abort mexSLOAD - sopen failed\n");

#ifdef mexSOPEN
		plhs[0] = HDR; 
#else
		plhs[0] = mxCreateDoubleMatrix(0,0, mxREAL);
		plhs[1] = HDR; 
#endif 		 
	if (VERBOSE_LEVEL>7) 
		mexPrintf("777: abort mexSLOAD - sopen failed\n");

		return; 
	}

#ifdef CHOLMOD_H
	RerefCHANNEL(hdr,rr,2);
#endif

	if (hdr->FLAG.OVERFLOWDETECTION != FlagOverflowDetection)
		mexPrintf("Warning mexSLOAD: Overflowdetection not supported in file %s\n",hdr->FileName);
	if (hdr->FLAG.UCAL != FlagUCAL)
		mexPrintf("Warning mexSLOAD: Flag UCAL is %i instead of %i (%s)\n",hdr->FLAG.UCAL,FlagUCAL,hdr->FileName);


	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[112] SOPEN-R finished NS=%i %i\n",hdr->NS,NS);

//	convert2to4_eventtable(hdr); 
		
#ifdef CHOLMOD_H
	if (hdr->Calib != NULL) {
		NS = hdr->Calib->ncol;
	}
	else 
#endif
	if ((NS<0) || ((NS==1) && (ChanList[0] == 0.0))) { 	// all channels
		for (k=0, NS=0; k<hdr->NS; ++k) {
			if (hdr->CHANNEL[k].OnOff) NS++; 
		}	
	}		
	else {		
		for (k=0; k<hdr->NS; ++k)
			hdr->CHANNEL[k].OnOff = 0; 	// reset
		for (k=0; k<NS; ++k) {
			int ch = (int)ChanList[k];
			if ((ch < 1) || (ch > hdr->NS)) 
				mexPrintf("Invalid channel number CHAN(%i) = %i!\n",k+1,ch); 
			else 	
				hdr->CHANNEL[ch-1].OnOff = 1;  // set
		}		
	}
	
	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"[113] NS=%i %i\n",hdr->NS,NS);

#ifndef mexSOPEN
	if (hdr->FLAG.ROW_BASED_CHANNELS)
		plhs[0] = mxCreateDoubleMatrix(NS, hdr->NRec*hdr->SPR, mxREAL);
	else
		plhs[0] = mxCreateDoubleMatrix(hdr->NRec*hdr->SPR, NS, mxREAL);

	count = sread(mxGetPr(plhs[0]), 0, hdr->NRec, hdr);
	hdr->NRec = count; 
#endif
	sclose(hdr);
#ifdef CHOLMOD_H
        if (hdr->Calib && hdr->rerefCHANNEL) {
		hdr->NS = hdr->Calib->ncol; 
                free(hdr->CHANNEL);
                hdr->CHANNEL = hdr->rerefCHANNEL;
                hdr->rerefCHANNEL = NULL; 
                hdr->Calib = NULL; 
        }                
#endif 
	if ((status=serror())) return;  

	if (VERBOSE_LEVEL>7) 
		fprintf(stderr,"\n[129] SREAD/SCLOSE on %s successful [%i,%i] [%Li,%i] %i.\n",hdr->FileName,hdr->data.size[0],hdr->data.size[1],hdr->NRec,count,NS);


//	hdr2ascii(hdr,stderr,4);	

#ifndef mexSOPEN 

	if (nlhs>1) { 
#endif

		char* mexFileName = (char*)mxMalloc(strlen(hdr->FileName)+1); 

		mxArray *tmp, *tmp2, *Patient, *Manufacturer, *ID, *EVENT, *Filter, *Flag, *FileType;
		uint16_t numfields;
		const char *fnames[] = {"TYPE","VERSION","FileName","T0","FILE","Patient",\
		"HeadLen","NS","SPR","NRec","SampleRate", "FLAG", \
		"EVENT","Label","LeadIdCode","PhysDimCode","PhysDim","Filter",\
		"PhysMax","PhysMin","DigMax","DigMin","Transducer","Cal","Off","GDFTYP","TOffset",\
		"LowPass","HighPass","Notch","ELEC","Impedance","fZ","AS","Dur","REC","Manufacturer",NULL};

		for (numfields=0; fnames[numfields++] != NULL; );
		HDR = mxCreateStructMatrix(1, 1, --numfields, fnames);

		mxSetField(HDR,0,"TYPE",mxCreateString(GetFileTypeString(hdr->TYPE)));
		mxSetField(HDR,0,"HeadLen",mxCreateDoubleScalar(hdr->HeadLen));
		mxSetField(HDR,0,"VERSION",mxCreateDoubleScalar(hdr->VERSION));
		mxSetField(HDR,0,"NS",mxCreateDoubleScalar(hdr->NS));
		mxSetField(HDR,0,"SPR",mxCreateDoubleScalar(hdr->SPR));
		mxSetField(HDR,0,"NRec",mxCreateDoubleScalar(hdr->NRec));
		mxSetField(HDR,0,"SampleRate",mxCreateDoubleScalar(hdr->SampleRate));
		mxSetField(HDR,0,"Dur",mxCreateDoubleScalar(hdr->SPR/hdr->SampleRate));
		mxSetField(HDR,0,"FileName",mxCreateCharMatrixFromStrings(1,&hdr->FileName));
                
		mxSetField(HDR,0,"T0",mxCreateDoubleScalar(ldexp(hdr->T0,-32)));

		/* Channel information */ 
#ifdef CHOLMOD_H
/*
        	if (hdr->Calib == NULL) { // is refering to &RR, do not destroy
		        mxArray *Calib = mxCreateDoubleMatrix(hdr->Calib->nrow, hdr->Calib->ncol, mxREAL);

        	}
*/
#endif
		mxArray *LeadIdCode  = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *PhysDimCode = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *GDFTYP      = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *PhysMax     = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *PhysMin     = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *DigMax      = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *DigMin      = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Cal         = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Off         = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Toffset     = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *ELEC_POS    = mxCreateDoubleMatrix(hdr->NS,3, mxREAL);
		mxArray *ELEC_Orient = mxCreateDoubleMatrix(hdr->NS,3, mxREAL);
		mxArray *ELEC_Area   = mxCreateDoubleMatrix(hdr->NS,1, mxREAL);
		mxArray *LowPass     = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *HighPass    = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Notch       = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Impedance   = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *fZ          = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *SPR         = mxCreateDoubleMatrix(1,hdr->NS, mxREAL);
		mxArray *Label       = mxCreateCellMatrix(hdr->NS,1);
		mxArray *Transducer  = mxCreateCellMatrix(hdr->NS,1);
		mxArray *PhysDim1    = mxCreateCellMatrix(hdr->NS,1);

		for (size_t k=0; k<hdr->NS; ++k) {
			*(mxGetPr(LeadIdCode)+k)  = (double)hdr->CHANNEL[k].LeadIdCode;
			*(mxGetPr(PhysDimCode)+k) = (double)hdr->CHANNEL[k].PhysDimCode;
			*(mxGetPr(GDFTYP)+k) 	  = (double)hdr->CHANNEL[k].GDFTYP;
			*(mxGetPr(PhysMax)+k) 	  = (double)hdr->CHANNEL[k].PhysMax;
			*(mxGetPr(PhysMin)+k) 	  = (double)hdr->CHANNEL[k].PhysMin;
			*(mxGetPr(DigMax)+k) 	  = (double)hdr->CHANNEL[k].DigMax;
			*(mxGetPr(DigMin)+k) 	  = (double)hdr->CHANNEL[k].DigMin;
			*(mxGetPr(Toffset)+k) 	  = (double)hdr->CHANNEL[k].TOffset;
			*(mxGetPr(Cal)+k) 	  = (double)hdr->CHANNEL[k].Cal;
			*(mxGetPr(Off)+k) 	  = (double)hdr->CHANNEL[k].Off;
			*(mxGetPr(SPR)+k) 	  = (double)hdr->CHANNEL[k].SPR;
			*(mxGetPr(LowPass)+k) 	  = (double)hdr->CHANNEL[k].LowPass;
			*(mxGetPr(HighPass)+k) 	  = (double)hdr->CHANNEL[k].HighPass;
			*(mxGetPr(Notch)+k) 	  = (double)hdr->CHANNEL[k].Notch;
			*(mxGetPr(Impedance)+k)	  = (double)hdr->CHANNEL[k].Impedance;
			*(mxGetPr(fZ)+k)	  = (double)hdr->CHANNEL[k].fZ;
			*(mxGetPr(ELEC_POS)+k) 	  = (double)hdr->CHANNEL[k].XYZ[0];
			*(mxGetPr(ELEC_POS)+k+hdr->NS) 	  = (double)hdr->CHANNEL[k].XYZ[1];
			*(mxGetPr(ELEC_POS)+k+hdr->NS*2)  = (double)hdr->CHANNEL[k].XYZ[2];
/*
			*(mxGetPr(ELEC_Orient)+k) 	  = (double)hdr->CHANNEL[k].Orientation[0];
			*(mxGetPr(ELEC_Orient)+k+hdr->NS) 	  = (double)hdr->CHANNEL[k].Orientation[1];
			*(mxGetPr(ELEC_Orient)+k+hdr->NS*2)  = (double)hdr->CHANNEL[k].Orientation[2];
			*(mxGetPr(ELEC_Area)+k) 	  = (double)hdr->CHANNEL[k].Area;
*/
			mxSetCell(Label,k,mxCreateString(hdr->CHANNEL[k].Label));
			mxSetCell(Transducer,k,mxCreateString(hdr->CHANNEL[k].Transducer));
			
			char p[MAX_LENGTH_PHYSDIM+1];
			PhysDim(hdr->CHANNEL[k].PhysDimCode,p);			
			mxSetCell(PhysDim1,k,mxCreateString(p));
		} 

		mxSetField(HDR,0,"LeadIdCode",LeadIdCode);
		mxSetField(HDR,0,"PhysDimCode",PhysDimCode);
		mxSetField(HDR,0,"GDFTYP",GDFTYP);
		mxSetField(HDR,0,"PhysMax",PhysMax);
		mxSetField(HDR,0,"PhysMin",PhysMin);
		mxSetField(HDR,0,"DigMax",DigMax);
		mxSetField(HDR,0,"DigMin",DigMin);
		mxSetField(HDR,0,"TOffset",Toffset);
		mxSetField(HDR,0,"Cal",Cal);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"Impedance",Impedance);
		mxSetField(HDR,0,"fZ",fZ);
		mxSetField(HDR,0,"Off",Off);
		mxSetField(HDR,0,"PhysDim",PhysDim1);
		mxSetField(HDR,0,"Transducer",Transducer);
		mxSetField(HDR,0,"Label",Label);

		const char* field[] = {"XYZ","Orientation","Area","GND","REF",NULL};
		for (numfields=0; field[numfields++] != 0; );
		tmp = mxCreateStructMatrix(1, 1, --numfields, field);
		mxSetField(tmp,0,"XYZ",ELEC_POS);
		mxSetField(tmp,0,"Orientation",ELEC_Orient);
		mxSetField(tmp,0,"Area",ELEC_Area);
		mxSetField(HDR,0,"ELEC",tmp);

		const char* field2[] = {"SPR",NULL};
		for (numfields=0; field2[numfields++] != 0; );
		tmp2 = mxCreateStructMatrix(1, 1, --numfields, field2);
		mxSetField(tmp2,0,"SPR",SPR);
		if (hdr->AS.bci2000!=NULL) {
			mxAddField(tmp2, "BCI2000");
			mxSetField(tmp2,0,"BCI2000",mxCreateString(hdr->AS.bci2000));
		}
		if (hdr->TYPE==Sigma) {	
			mxAddField(tmp2, "H1");
			mxSetField(tmp2,0,"H1",mxCreateString((char*)hdr->AS.Header));
		}	
		mxSetField(HDR,0,"AS",tmp2);
				
		/* FLAG */
		const char* field3[] = {"UCAL","OVERFLOWDETECTION","ROW_BASED_CHANNELS",NULL};
		for (numfields=0; field3[numfields++] != 0; );
		Flag = mxCreateStructMatrix(1, 1, --numfields, field3);
#ifdef MX_API_VER
                // Matlab 
       		mxSetField(Flag,0,"UCAL",mxCreateLogicalScalar(hdr->FLAG.UCAL));
        	mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateLogicalScalar(hdr->FLAG.OVERFLOWDETECTION));
        	mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateLogicalScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#else 
                // mxCreateLogicalScalar are not included in Octave 3.0 
	        mxSetField(Flag,0,"UCAL",mxCreateDoubleScalar(hdr->FLAG.UCAL));
       		mxSetField(Flag,0,"OVERFLOWDETECTION",mxCreateDoubleScalar(hdr->FLAG.OVERFLOWDETECTION));
       		mxSetField(Flag,0,"ROW_BASED_CHANNELS",mxCreateDoubleScalar(hdr->FLAG.ROW_BASED_CHANNELS));
#endif
		mxSetField(HDR,0,"FLAG",Flag);

		/* Filter */ 
		const char *filter_fields[] = {"HighPass","LowPass","Notch",NULL};
		for (numfields=0; filter_fields[numfields++] != 0; );
		Filter = mxCreateStructMatrix(1, 1, --numfields, filter_fields);
		mxSetField(Filter,0,"LowPass",LowPass);
		mxSetField(Filter,0,"HighPass",HighPass);
		mxSetField(Filter,0,"Notch",Notch);
		mxSetField(HDR,0,"Filter",Filter);

		/* annotation, marker, event table */
		const char *event_fields[] = {"SampleRate","TYP","POS","DUR","CHN","Desc",NULL};
		
		if (hdr->EVENT.DUR == NULL)
			EVENT = mxCreateStructMatrix(1, 1, 3, event_fields);
		else {	
			EVENT = mxCreateStructMatrix(1, 1, 5, event_fields);
			mxArray *DUR = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			mxArray *CHN = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
			for (size_t k=0; k<hdr->EVENT.N; ++k) {
				*(mxGetPr(DUR)+k) = (double)hdr->EVENT.DUR[k];
				*(mxGetPr(CHN)+k) = (double)hdr->EVENT.CHN[k];  // channels use a 1-based index, 0 indicates all channels
			} 
			mxSetField(EVENT,0,"DUR",DUR);
			mxSetField(EVENT,0,"CHN",CHN);
		}

		if (hdr->EVENT.CodeDesc != NULL) {
			mxAddField(EVENT, "CodeDesc");
			mxArray *CodeDesc = mxCreateCellMatrix(hdr->EVENT.LenCodeDesc-1,1);
			for (size_t k=1; k < hdr->EVENT.LenCodeDesc; ++k) {
				mxSetCell(CodeDesc,k-1,mxCreateString(hdr->EVENT.CodeDesc[k]));
			} 
			mxSetField(EVENT,0,"CodeDesc",CodeDesc);
		}	

		mxArray *TYP = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
		mxArray *POS = mxCreateDoubleMatrix(hdr->EVENT.N,1, mxREAL);
		for (size_t k=0; k<hdr->EVENT.N; ++k) {
			*(mxGetPr(TYP)+k) = (double)hdr->EVENT.TYP[k];
			*(mxGetPr(POS)+k) = (double)hdr->EVENT.POS[k]+1;   // conversion from 0-based to 1-based indexing 
		} 
		mxSetField(EVENT,0,"TYP",TYP);
		mxSetField(EVENT,0,"POS",POS);
		mxSetField(EVENT,0,"SampleRate",mxCreateDoubleScalar(hdr->EVENT.SampleRate));
		mxSetField(HDR,0,"EVENT",EVENT);

		/* Record identification */ 
		const char *ID_fields[] = {"Recording","Technician","Hospital","Equipment","IPaddr",NULL};
		for (numfields=0; ID_fields[numfields++] != 0; );
		ID = mxCreateStructMatrix(1, 1, --numfields, ID_fields);
		mxSetField(ID,0,"Recording",mxCreateString(hdr->ID.Recording));
		mxSetField(ID,0,"Technician",mxCreateString(hdr->ID.Technician));
		mxSetField(ID,0,"Hospital",mxCreateString(hdr->ID.Hospital));
		mxSetField(ID,0,"Equipment",mxCreateString((char*)&hdr->ID.Equipment));
		int len = 4; 
		uint8_t IPv6=0;
		for (uint8_t k=4; k<16; k++) IPv6 |= hdr->IPaddr[k];
		if (IPv6) len=16; 
		mxArray *IPaddr = mxCreateNumericMatrix(1,len,mxUINT8_CLASS,mxREAL);
		memcpy(mxGetData(IPaddr),hdr->IPaddr,len);
		mxSetField(ID,0,"IPaddr",IPaddr); 
		mxSetField(HDR,0,"REC",ID);

		/* Patient Information */ 
		const char *patient_fields[] = {"Sex","Handedness","Id","Name","Weight","Height","Birthday",NULL};
		for (numfields=0; patient_fields[numfields++] != 0; );
		Patient = mxCreateStructMatrix(1, 1, --numfields, patient_fields);
		const char *strarray[1];
		if (hdr->Patient.Name) {
			strarray[0] = hdr->Patient.Name; 
			mxSetField(Patient,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		if (hdr->Patient.Id) {
			strarray[0] = hdr->Patient.Id; 
			mxSetField(Patient,0,"Id",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		mxSetField(Patient,0,"Handedness",mxCreateDoubleScalar(hdr->Patient.Handedness));

		mxSetField(Patient,0,"Sex",mxCreateDoubleScalar(hdr->Patient.Sex));
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar((double)hdr->Patient.Weight));
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar((double)hdr->Patient.Height));
		mxSetField(Patient,0,"Birthday",mxCreateDoubleScalar(ldexp(hdr->Patient.Birthday,-32)));

		double d;
		if (hdr->Patient.Weight==0)		d = 0.0/0.0;	// not-a-number		
		else if (hdr->Patient.Weight==255)	d = 1.0/0.0;	// Overflow
		else					d = (double)hdr->Patient.Weight;
		mxSetField(Patient,0,"Weight",mxCreateDoubleScalar(d));
			
		if (hdr->Patient.Height==0)		d = 0.0/0.0;	// not-a-number		
		else if (hdr->Patient.Height==255)	d = 1.0/0.0;	// Overflow
		else					d = (double)hdr->Patient.Height;
		mxSetField(Patient,0,"Height",mxCreateDoubleScalar(d));
	
		/* Manufacturer Information */ 
		const char *manufacturer_fields[] = {"Name","Model","Version","SerialNumber",NULL};
		for (numfields=0; manufacturer_fields[numfields++] != 0; );
		Manufacturer = mxCreateStructMatrix(1, 1, --numfields, manufacturer_fields);
		if (hdr->ID.Manufacturer.Name) {
			strarray[0] = hdr->ID.Manufacturer.Name;
			mxSetField(Manufacturer,0,"Name",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		if (hdr->ID.Manufacturer.Model) {
			strarray[0] = hdr->ID.Manufacturer.Model;
			mxSetField(Manufacturer,0,"Model",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		if (hdr->ID.Manufacturer.Version) {
			strarray[0] = hdr->ID.Manufacturer.Version;
			mxSetField(Manufacturer,0,"Version",mxCreateCharMatrixFromStrings(1,strarray));
		}	
		if (hdr->ID.Manufacturer.SerialNumber) {
			strarray[0] = hdr->ID.Manufacturer.SerialNumber;
			mxSetField(Manufacturer,0,"SerialNumber",mxCreateCharMatrixFromStrings(1,strarray));
		}
		mxSetField(HDR,0,"Manufacturer",Manufacturer);

	if (VERBOSE_LEVEL>8) 
		fprintf(stdout,"[148] going for SCLOSE\n");

		mxSetField(HDR,0,"Patient",Patient);

#ifndef mexSOPEN
		plhs[1] = HDR; 
	}
#else
	plhs[0] = HDR; 
#endif

	if (VERBOSE_LEVEL>7) fprintf(stdout,"[151] going for SCLOSE\n");
#ifdef CHOLMOD_H
	hdr->Calib = NULL; // is refering to &RR, do not destroy
#endif
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[156] SCLOSE finished\n");
	destructHDR(hdr);
	hdr = NULL; 
	if (VERBOSE_LEVEL>7) fprintf(stdout,"[157] SCLOSE finished\n");
};
Example #3
0
/**
 * Adds a variadic log-message to the message-list for the current thread.
 *
 * This function is thread-safe.
 *
 * @retval 0            Success
 * @retval EAGAIN       Failure due to the buffer being too small for the
 *                      message.  The buffer has been expanded and the client
 *                      should call this function again.
 * @retval EINVAL       There are insufficient arguments. Error message logged.
 * @retval EILSEQ       A wide-character code that doesn't correspond to a
 *                      valid character has been detected. Error message logged.
 * @retval ENOMEM       Out-of-memory. Error message logged.
 * @retval EOVERFLOW    The length of the message is greater than {INT_MAX}.
 *                      Error message logged.
 */
int nplVadd(
    const char* const   fmt,  /**< The message format or NULL for no message */
    va_list             args) /**< The arguments referenced by the format. */
{
    int                 status = 0; /* default success */

    if (NULL != fmt) {
        List*   list = getList();

        if (NULL != list) {
            Message*    msg = (NULL == list->last) ? list->first :
                list->last->next;

            status = 0;

            if (msg == NULL) {
                msg = (Message*)malloc(sizeof(Message));

                if (msg == NULL) {
                    status = errno;

                    lock();
                    serror("nplVadd(): malloc(%lu) failure",
                        (unsigned long)sizeof(Message));
                    unlock();
                }
                else {
                    char*   string = (char*)malloc(DEFAULT_STRING_SIZE);

                    if (NULL == string) {
                        status = errno;

                        lock();
                        serror("nplVadd(): malloc(%lu) failure",
                            (unsigned long)DEFAULT_STRING_SIZE);
                        unlock();
                    }
                    else {
                        msg->string = string;
                        msg->size = DEFAULT_STRING_SIZE;
                        msg->next = NULL;

                        if (NULL == list->first)
                            list->first = msg;  /* very first message */
                    }
                }
            }

            if (0 == status) {
                int nbytes = vsnprintf(msg->string, msg->size, fmt, args);

                if (0 > nbytes) {
                    status = errno;

                    lock();
                    serror("nplVadd(): vsnprintf() failure");
                    unlock();
                }
                else if (msg->size <= nbytes) {
                    /* The buffer is too small for the message */
                    size_t  size = nbytes + 1;
                    char*   string = (char*)malloc(size);

                    if (NULL == string) {
                        status = errno;

                        lock();
                        serror("nplVadd(): malloc(%lu) failure",
                            (unsigned long)size);
                        unlock();
                    }
                    else {
                        free(msg->string);

                        msg->string = string;
                        msg->size = size;
                        status = EAGAIN;
                    }
                }
                else {
                    if (NULL != list->last)
                        list->last->next = msg;

                    list->last = msg;
                }
            }                               /* have a message structure */
        }                                   /* message-list isn't NULL */
    }                                       /* arguments aren't NULL */

    return status;
}
Example #4
0
/**
 * Unlocks this module's lock.
 *
 * This function is thread-safe. On entry, this module's lock shall be locked
 * by the current thread.
 */
static void unlock(void)
{
    if (pthread_mutex_unlock(&mutex) != 0)
        serror("Couldn't unlock logging mutex");
}
Example #5
0
stfio::filetype stfio_file_type(HDRTYPE* hdr) {
#ifdef __LIBBIOSIG2_H__
        switch (biosig_get_filetype(hdr)) {
#else
        switch (hdr->TYPE) {
#endif

#if (BIOSIG_VERSION > 10500)
        case ABF2:	return stfio::abf;
#endif
        case ABF:	return stfio::abf;
        case ATF:	return stfio::atf;
        case CFS:	return stfio::cfs;
        case HEKA:	return stfio::heka;
        case HDF:	return stfio::hdf5;
#if (BIOSIG_VERSION > 10403)
        case AXG:	return stfio::axg;
        case IBW:	return stfio::igor;
        case SMR:	return stfio::son;
#endif
        default:	return stfio::none;
        }
}

#if (defined(WITH_BIOSIG) || defined(WITH_BIOSIG2))
bool stfio::check_biosig_version(int a, int b, int c) {
	return (BIOSIG_VERSION >= 10000*a + 100*b + c);
}
#endif

stfio::filetype stfio::importBiosigFile(const std::string &fName, Recording &ReturnData, ProgressInfo& progDlg) {

    std::string errorMsg("Exception while calling std::importBSFile():\n");
    std::string yunits;
    stfio::filetype type;

    // =====================================================================================================================
    //
    // importBiosig opens file with libbiosig
    //	- performs an automated identification of the file format
    //  - and decides whether the data is imported through importBiosig (currently CFS, HEKA, ABF1, GDF, and others)
    //  - or handed back to other import*File functions (currently ABF2, AXG, HDF5)
    //
    // There are two implementations, level-1 and level-2 interface of libbiosig.
    //   level 1 is used when -DWITH_BIOSIG, -lbiosig
    //   level 2 is used when -DWITH_BIOSIG2, -lbiosig2
    //
    //   level 1 is better tested, but it does not provide ABI compatibility between MinGW and VisualStudio
    //   level 2 interface has been developed to provide ABI compatibility, but it is less tested
    //      and the API might still undergo major changes.
    // =====================================================================================================================


#ifdef __LIBBIOSIG2_H__

    HDRTYPE* hdr =  sopen( fName.c_str(), "r", NULL );
    if (hdr==NULL) {
        ReturnData.resize(0);
        return stfio::none;
    }

    type = stfio_file_type(hdr);
    if (biosig_check_error(hdr)) {
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }
    enum FileFormat biosig_filetype=biosig_get_filetype(hdr);
    if (biosig_filetype==ATF || biosig_filetype==ABF2 || biosig_filetype==HDF ) {
        // ATF, ABF2 and HDF5 support should be handled by importATF, and importABF, and importHDF5 not importBiosig
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }

    // earlier versions of biosig support only the file type identification, but did not properly read the files
    if ( (BIOSIG_VERSION < 10603)
      && (biosig_filetype==AXG)
       ) {
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }

    // ensure the event table is in chronological order	
    sort_eventtable(hdr);

    // allocate local memory for intermediate results;
    const int strSize=100;
    char str[strSize];

    /*
	count sections and generate list of indices indicating start and end of sweeps
     */	

    double fs = biosig_get_eventtable_samplerate(hdr);
    size_t numberOfEvents = biosig_get_number_of_events(hdr);
    size_t nsections = biosig_get_number_of_segments(hdr);
    size_t *SegIndexList = (size_t*)malloc((nsections+1)*sizeof(size_t));
    SegIndexList[0] = 0;
    SegIndexList[nsections] = biosig_get_number_of_samples(hdr);
    std::string annotationTableDesc = std::string();
    for (size_t k=0, n=0; k < numberOfEvents; k++) {
        uint32_t pos;
        uint16_t typ;
#if BIOSIG_VERSION < 10605
        char *desc;
#else
        const char *desc;
#endif
        /*
        uint32_t dur;
        uint16_t chn;
        gdftype  timestamp;
        */

        biosig_get_nth_event(hdr, k, &typ, &pos, NULL, NULL, NULL, &desc);

        if (typ == 0x7ffe) {
            SegIndexList[++n] = pos;
        }
        else if (typ < 256) {
            sprintf(str,"%f s:\t%s\n", pos/fs, desc);
            annotationTableDesc += std::string( str );
        }
    }
    int numberOfChannels = biosig_get_number_of_channels(hdr);

    /*************************************************************************
        rescale data to mV and pA
     *************************************************************************/
    for (int ch=0; ch < numberOfChannels; ++ch) {
        CHANNEL_TYPE *hc = biosig_get_channel(hdr, ch);
        switch (biosig_channel_get_physdimcode(hc) & 0xffe0) {
        case 4256:  // Volt
		//biosig_channel_scale_to_unit(hc, "mV");
		biosig_channel_change_scale_to_physdimcode(hc, 4274);
		break;
        case 4160:  // Ampere
		//biosig_channel_scale_to_unit(hc, "pA");
		biosig_channel_change_scale_to_physdimcode(hc, 4181);
		break;
	    }
    }

    /*************************************************************************
        read bulk data
     *************************************************************************/
    biosig_data_type *data = biosig_get_data(hdr, 0);
    size_t SPR = biosig_get_number_of_samples(hdr);

#ifdef _STFDEBUG
    std::cout << "Number of events: " << numberOfEvents << std::endl;
    /*int res = */ hdr2ascii(hdr, stdout, 4);
#endif

    for (int NS=0; NS < numberOfChannels; ) {
        CHANNEL_TYPE *hc = biosig_get_channel(hdr, NS);
        Channel TempChannel(nsections);
        TempChannel.SetChannelName(biosig_channel_get_label(hc));
        TempChannel.SetYUnits(biosig_channel_get_physdim(hc));

        for (size_t ns=1; ns<=nsections; ns++) {
	        size_t SPS = SegIndexList[ns]-SegIndexList[ns-1];	// length of segment, samples per segment

		int progbar = int(100.0*(1.0*ns/nsections + NS)/numberOfChannels);
		std::ostringstream progStr;
		progStr << "Reading channel #" << NS + 1 << " of " << numberOfChannels
			<< ", Section #" << ns << " of " << nsections;
		progDlg.Update(progbar, progStr.str());

		/* unused //
		char sweepname[20];
		sprintf(sweepname,"sweep %i",(int)ns);
		*/
		Section TempSection(
                                SPS, // TODO: hdr->nsamplingpoints[nc][ns]
                                "" // TODO: hdr->sectionname[nc][ns]
        );

		std::copy(&(data[NS*SPR + SegIndexList[ns-1]]),
			  &(data[NS*SPR + SegIndexList[ns]]),
			  TempSection.get_w().begin() );

        try {
            TempChannel.InsertSection(TempSection, ns-1);
        }
        catch (...) {
			ReturnData.resize(0);
			destructHDR(hdr);
			return type;
		}
	}
    try {
        if ((int)ReturnData.size() < numberOfChannels) {
            ReturnData.resize(numberOfChannels);
		}
		ReturnData.InsertChannel(TempChannel, NS++);
    }
    catch (...) {
		ReturnData.resize(0);
		destructHDR(hdr);
		return type;
        }
    }

    free(SegIndexList);

    ReturnData.SetComment ( biosig_get_recording_id(hdr) );

    sprintf(str,"v%i.%i.%i (compiled on %s %s)",BIOSIG_VERSION_MAJOR,BIOSIG_VERSION_MINOR,BIOSIG_PATCHLEVEL,__DATE__,__TIME__);
    std::string Desc = std::string("importBiosig with libbiosig ")+std::string(str) + " ";

    const char* tmpstr;
    if ((tmpstr=biosig_get_technician(hdr)))
            Desc += std::string ("\nTechnician:\t") + std::string (tmpstr) + " ";
    Desc += std::string( "\nCreated with: ");
    if ((tmpstr=biosig_get_manufacturer_name(hdr)))
        Desc += std::string( tmpstr ) + " ";
    if ((tmpstr=biosig_get_manufacturer_model(hdr)))
        Desc += std::string( tmpstr ) + " ";
    if ((tmpstr=biosig_get_manufacturer_version(hdr)))
        Desc += std::string( tmpstr ) + " ";
    if ((tmpstr=biosig_get_manufacturer_serial_number(hdr)))
        Desc += std::string( tmpstr ) + " ";

    Desc += std::string ("\nUser specified Annotations:\n")+annotationTableDesc;

    ReturnData.SetFileDescription(Desc);

#if (BIOSIG_VERSION > 10509)
    tmpstr = biosig_get_application_specific_information(hdr);
    if (tmpstr != NULL) /* MSVC2008 can not properly handle std::string( (char*)NULL ) */
        ReturnData.SetGlobalSectionDescription(tmpstr);
#endif

    ReturnData.SetXScale(1000.0/biosig_get_samplerate(hdr));
    ReturnData.SetXUnits("ms");
    ReturnData.SetScaling("biosig scaling factor");

    /*************************************************************************
        Date and time conversion
     *************************************************************************/
    struct tm T;
    biosig_get_startdatetime(hdr, &T);
    ReturnData.SetDateTime(T);

    destructHDR(hdr);


#else  // #ifndef __LIBBIOSIG2_H__


    HDRTYPE* hdr =  sopen( fName.c_str(), "r", NULL );
    if (hdr==NULL) {
        ReturnData.resize(0);
        return stfio::none;
    }
    type = stfio_file_type(hdr);

#if !defined(BIOSIG_VERSION) || (BIOSIG_VERSION < 10501)
    if (hdr->TYPE==ABF) {
        /*
           biosig v1.5.0 and earlier does not always return
           with a proper error message for ABF files.
           This causes problems with the ABF fallback mechanism
        */
#else
    if ( hdr->TYPE==ABF2 ) {
        // ABF2 support should be handled by importABF not importBiosig
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }
    if (hdr->TYPE==ABF && hdr->AS.B4C_ERRNUM) {
        /* this triggers the fall back mechanims w/o reporting an error message */
#endif
        ReturnData.resize(0);
        destructHDR(hdr);	// free allocated memory
        return type;
    }

#if defined(BIOSIG_VERSION) && (BIOSIG_VERSION > 10400)
    if (hdr->AS.B4C_ERRNUM) {
#else
    if (B4C_ERRNUM) {
#endif
        ReturnData.resize(0);
        destructHDR(hdr);	// free allocated memory
        return type;
    }
    if ( hdr->TYPE==ATF || hdr->TYPE==HDF) {
        // ATF, HDF5 support should be handled by importATF and importHDF5 not importBiosig
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }

    // earlier versions of biosig support only the file type identification, but did not read AXG files
#if defined(BIOSIG_VERSION) && (BIOSIG_VERSION > 10403)
    if ( (BIOSIG_VERSION < 10600)
         && (hdr->TYPE==AXG)
       ) {
        // biosig's AXG import crashes on Windows at this time
        ReturnData.resize(0);
        destructHDR(hdr);
        return type;
    }
#endif
    
    // ensure the event table is in chronological order
    sort_eventtable(hdr);

    // allocate local memory for intermediate results;
    const int strSize=100;
    char str[strSize];

    /*
	count sections and generate list of indices indicating start and end of sweeps
     */
    size_t numberOfEvents = hdr->EVENT.N;
    size_t LenIndexList = 256;
    if (LenIndexList > numberOfEvents) LenIndexList = numberOfEvents + 2;
    size_t *SegIndexList = (size_t*)malloc(LenIndexList*sizeof(size_t));
    uint32_t nsections = 0;
    SegIndexList[nsections] = 0;
    size_t MaxSectionLength = 0;
    for (size_t k=0; k <= numberOfEvents; k++) {
        if (LenIndexList <= nsections+2) {
            // allocate more memory as needed
		    LenIndexList *=2;
		    SegIndexList = (size_t*)realloc(SegIndexList, LenIndexList*sizeof(size_t));
	    }
        /*
            count number of sections and stores it in nsections;
            EVENT.TYP==0x7ffe indicate number of breaks between sweeps
	        SegIndexList includes index to first sample and index to last sample,
	        thus, the effective length of SegIndexList is the number of 0x7ffe plus two.
	    */
        if (0)                              ;
        else if (k >= hdr->EVENT.N)         SegIndexList[++nsections] = hdr->NRec*hdr->SPR;
        else if (hdr->EVENT.TYP[k]==0x7ffe) SegIndexList[++nsections] = hdr->EVENT.POS[k];
        else                                continue;

        size_t SPS = SegIndexList[nsections]-SegIndexList[nsections-1];	// length of segment, samples per segment
	    if (MaxSectionLength < SPS) MaxSectionLength = SPS;
    }

    int numberOfChannels = 0;
    for (int k=0; k < hdr->NS; k++)
        if (hdr->CHANNEL[k].OnOff==1)
            numberOfChannels++;

    /*************************************************************************
        rescale data to mV and pA
     *************************************************************************/    
    for (int ch=0; ch < hdr->NS; ++ch) {
        CHANNEL_TYPE *hc = hdr->CHANNEL+ch;
        if (hc->OnOff != 1) continue;
        double scale = PhysDimScale(hc->PhysDimCode); 
        switch (hc->PhysDimCode & 0xffe0) {
        case 4256:  // Volt
                hc->PhysDimCode = 4274; // = PhysDimCode("mV");
                scale *=1e3;   // V->mV
                hc->PhysMax *= scale;         
                hc->PhysMin *= scale;         
                hc->Cal *= scale;         
                hc->Off *= scale;         
                break; 
        case 4160:  // Ampere
                hc->PhysDimCode = 4181; // = PhysDimCode("pA");
                scale *=1e12;   // A->pA
                hc->PhysMax *= scale;         
                hc->PhysMin *= scale;         
                hc->Cal *= scale;         
                hc->Off *= scale;         
                break; 
        }     
    }

    /*************************************************************************
        read bulk data 
     *************************************************************************/    
    hdr->FLAG.ROW_BASED_CHANNELS = 0;
    /* size_t blks = */ sread(NULL, 0, hdr->NRec, hdr);
    biosig_data_type *data = hdr->data.block;
    size_t SPR = hdr->NRec*hdr->SPR;

#ifdef _STFDEBUG
    std::cout << "Number of events: " << numberOfEvents << std::endl;
    /*int res = */ hdr2ascii(hdr, stdout, 4);
#endif

    int NS = 0;   // number of non-empty channels
    for (size_t nc=0; nc < hdr->NS; ++nc) {

        if (hdr->CHANNEL[nc].OnOff == 0) continue;

        Channel TempChannel(nsections);
        TempChannel.SetChannelName(hdr->CHANNEL[nc].Label);
#if defined(BIOSIG_VERSION) && (BIOSIG_VERSION > 10301)
        TempChannel.SetYUnits(PhysDim3(hdr->CHANNEL[nc].PhysDimCode));
#else
        PhysDim(hdr->CHANNEL[nc].PhysDimCode,str);
        TempChannel.SetYUnits(str);
#endif

        for (size_t ns=1; ns<=nsections; ns++) {
	        size_t SPS = SegIndexList[ns]-SegIndexList[ns-1];	// length of segment, samples per segment

		int progbar = 100.0*(1.0*ns/nsections + NS)/numberOfChannels;
		std::ostringstream progStr;
		progStr << "Reading channel #" << NS + 1 << " of " << numberOfChannels
			<< ", Section #" << ns << " of " << nsections;
		progDlg.Update(progbar, progStr.str());

		/* unused //
		char sweepname[20];
		sprintf(sweepname,"sweep %i",(int)ns);		
		*/
		Section TempSection(
                                SPS, // TODO: hdr->nsamplingpoints[nc][ns]
                                "" // TODO: hdr->sectionname[nc][ns]
            	);

		std::copy(&(data[NS*SPR + SegIndexList[ns-1]]),
			  &(data[NS*SPR + SegIndexList[ns]]),
			  TempSection.get_w().begin() );

        try {
            TempChannel.InsertSection(TempSection, ns-1);
        }
        catch (...) {
			ReturnData.resize(0);
			destructHDR(hdr);
			return type;
		}
	}        
    try {
        if ((int)ReturnData.size() < numberOfChannels) {
            ReturnData.resize(numberOfChannels);
        }
        ReturnData.InsertChannel(TempChannel, NS++);
    }
    catch (...) {
		ReturnData.resize(0);
		destructHDR(hdr);
		return type;
        }
    }

    free(SegIndexList); 	

    ReturnData.SetComment ( hdr->ID.Recording );

    sprintf(str,"v%i.%i.%i (compiled on %s %s)",BIOSIG_VERSION_MAJOR,BIOSIG_VERSION_MINOR,BIOSIG_PATCHLEVEL,__DATE__,__TIME__);
    std::string Desc = std::string("importBiosig with libbiosig ")+std::string(str);

    if (hdr->ID.Technician)
            Desc += std::string ("\nTechnician:\t") + std::string (hdr->ID.Technician);
    Desc += std::string( "\nCreated with: ");
    if (hdr->ID.Manufacturer.Name)
        Desc += std::string( hdr->ID.Manufacturer.Name );
    if (hdr->ID.Manufacturer.Model)
        Desc += std::string( hdr->ID.Manufacturer.Model );
    if (hdr->ID.Manufacturer.Version)
        Desc += std::string( hdr->ID.Manufacturer.Version );
    if (hdr->ID.Manufacturer.SerialNumber)
        Desc += std::string( hdr->ID.Manufacturer.SerialNumber );

    Desc += std::string ("\nUser specified Annotations:\n");
    for (size_t k=0; k < numberOfEvents; k++) {
        if (hdr->EVENT.TYP[k] < 256) {
            sprintf(str,"%f s:\t",hdr->EVENT.POS[k]/hdr->EVENT.SampleRate);
            Desc += std::string( str );
            Desc += std::string( hdr->EVENT.CodeDesc[hdr->EVENT.TYP[k]] ) + "\n";
        }
    }
    ReturnData.SetFileDescription(Desc);
    // hdr->AS.bci2000 is an alias to hdr->AS.fpulse, which available only in libbiosig v1.6.0 or later

    if (hdr->AS.bci2000) ReturnData.SetGlobalSectionDescription(std::string(hdr->AS.bci2000));

    ReturnData.SetXScale(1000.0/hdr->SampleRate);
    ReturnData.SetXUnits("ms");
    ReturnData.SetScaling("biosig scaling factor");

    /*************************************************************************
        Date and time conversion
     *************************************************************************/
    struct tm T;
#if (BIOSIG_VERSION_MAJOR > 0)
    gdf_time2tm_time_r(hdr->T0, &T);
#else
    struct tm* Tp;
    Tp = gdf_time2tm_time(hdr->T0);
    T = *Tp;
#endif

    ReturnData.SetDateTime(T);

    destructHDR(hdr);

#endif
    return stfio::biosig;
}


    // =====================================================================================================================
    //
    // Save file with libbiosig into GDF format
    //
    // There basically two implementations, one with libbiosig before v1.6.0 and
    // and one for libbiosig v1.6.0 and later
    //
    // =====================================================================================================================

bool stfio::exportBiosigFile(const std::string& fName, const Recording& Data, stfio::ProgressInfo& progDlg) {
/*
    converts the internal data structure to libbiosig's internal structure
    and saves the file as gdf file.

    The data in converted into the raw data format, and not into the common
    data matrix.
*/

#ifdef __LIBBIOSIG2_H__

    size_t numberOfChannels = Data.size();
    HDRTYPE* hdr = constructHDR(numberOfChannels, 0);

	/* Initialize all header parameters */
    biosig_set_filetype(hdr, GDF);

    biosig_set_startdatetime(hdr, Data.GetDateTime());

    const char *xunits = Data.GetXUnits().c_str();
    uint16_t pdc = PhysDimCode(xunits);

    if ((pdc & 0xffe0) != PhysDimCode("s")) {
        fprintf(stderr,"Stimfit exportBiosigFile: xunits [%s] has not proper units, assume [ms]\n",Data.GetXUnits().c_str());
        pdc = PhysDimCode("ms");
    }

    double fs = 1.0/(PhysDimScale(pdc) * Data.GetXScale());
    biosig_set_samplerate(hdr, fs);

#if (BIOSIG_VERSION < 10700)
    biosig_set_flags(hdr, 0, 0, 0);
#else
    biosig_reset_flag(hdr, BIOSIG_FLAG_COMPRESSION | BIOSIG_FLAG_UCAL | BIOSIG_FLAG_OVERFLOWDETECTION | BIOSIG_FLAG_ROW_BASED_CHANNELS );
#endif

    size_t k, m, numberOfEvents=0;
    size_t NRec=0;	// corresponds to hdr->NRec
    size_t SPR=1;	// corresponds to hdr->SPR
    size_t chSPR=0;	// corresponds to hc->SPR

    /* Initialize all channel parameters */
#ifndef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR
	size_t *chanSPR = (size_t*)malloc(numberOfChannels*sizeof(size_t));
#endif
    for (k = 0; k < numberOfChannels; ++k) {
        CHANNEL_TYPE *hc = biosig_get_channel(hdr, k);

		biosig_channel_set_datatype_to_double(hc);
		biosig_channel_set_scaling(hc, 1e9, -1e9, 1e9, -1e9);
		biosig_channel_set_label(hc, Data[k].GetChannelName().c_str());
		biosig_channel_set_physdim(hc, Data[k].GetYUnits().c_str());

		biosig_channel_set_filter(hc, NAN, NAN, NAN);
		biosig_channel_set_timing_offset(hc, 0.0);
		biosig_channel_set_impedance(hc, NAN);

        chSPR    = SPR;

        // each segment gets one marker, roughly
        numberOfEvents += Data[k].size();

        size_t m,len = 0;
        for (len=0, m = 0; m < Data[k].size(); ++m) {
            unsigned div = lround(Data[k][m].GetXScale()/Data.GetXScale());
            chSPR = lcm(chSPR,div);  // sampling interval of m-th segment in k-th channel
            len += div*Data[k][m].size();
        }
        SPR = lcm(SPR, chSPR);

        /*
            hc->SPR (i.e. chSPR) is 'abused' to store final hdr->SPR/hc->SPR, this is corrected in the loop below
            its a hack to avoid the need for another malloc().
        */
#ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR
        biosig_channel_set_samples_per_record(hc, chSPR);
#else
        chanSPR[k]=chSPR;
#endif

        if (k==0) {
            NRec = len;
        }
        else if ((size_t)NRec != len) {
            destructHDR(hdr);
            throw std::runtime_error("File can't be exported:\n"
                "No data or traces have different sizes" );

            return false;
        }
    }

    biosig_set_number_of_samples(hdr, NRec, SPR);
    size_t bpb = 0;
    for (k = 0; k < numberOfChannels; ++k) {
        CHANNEL_TYPE *hc = biosig_get_channel(hdr, k);
        // the 'abuse' of hc->SPR described above is corrected
#ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR
        size_t spr = biosig_channel_get_samples_per_record(hc);
        spr = SPR / spr;
        biosig_channel_set_samples_per_record(hc, spr);
#else
        size_t spr = SPR/chanSPR[k];
        chanSPR[k] = spr;
#endif
        bpb += spr * 8; /* its always double */
    }

	/***
	    build Event table for storing segment information
	    pre-allocate memory for even table
         ***/

        numberOfEvents *= 2;    // about two events per segment
        biosig_set_number_of_events(hdr, numberOfEvents);

    /* check whether all segments have same size */
    {
        char flag = (numberOfChannels > 0);
        size_t m, POS, pos;
        for (k=0; k < numberOfChannels; ++k) {
            pos = Data[k].size();
            if (k==0)
                POS = pos;
            else
                flag &= (POS == pos);
        }
        for (m=0; flag && (m < Data[(size_t)0].size()); ++m) {
            for (k=0; k < biosig_get_number_of_channels(hdr); ++k) {
                pos = Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale());
                if (k==0)
                    POS = pos;
                else
                    flag &= (POS == pos);
            }
        }
        if (!flag) {
            destructHDR(hdr);
            throw std::runtime_error(
                    "File can't be exported:\n"
                    "Traces have different sizes or no channels found"
            );
            return false;
        }
    }

        size_t N=0;
        k=0;
        size_t pos = 0;
        for (m=0; m < (Data[k].size()); ++m) {
            if (pos > 0) {
                uint16_t typ=0x7ffe;
                uint32_t pos32=pos;
                uint16_t chn=0;
                uint32_t dur=0;
                // set break marker
                biosig_set_nth_event(hdr, N++, &typ, &pos32, &chn, &dur, NULL, NULL);
                /*
                // set annotation
                const char *Desc = Data[k][m].GetSectionDescription().c_str();
                 if (Desc != NULL && strlen(Desc)>0)
                    biosig_set_nth_event(hdr, N++, NULL, &pos32, &chn, &dur, NULL, Desc);   // TODO
                */
            }
            pos += Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale());
        }

        biosig_set_number_of_events(hdr, N);
        biosig_set_eventtable_samplerate(hdr, fs);
        sort_eventtable(hdr);

        /* convert data into GDF rawdata from  */
        uint8_t *rawdata = (uint8_t*)malloc(bpb * NRec);

        size_t bi=0;
	for (k=0; k < numberOfChannels; ++k) {
        CHANNEL_TYPE *hc = biosig_get_channel(hdr, k);
#ifdef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR
        size_t chSPR = biosig_channel_get_samples_per_record(hc);
#else
        size_t chSPR = chanSPR[k];
#endif
        size_t m,n,len=0;
        for (m=0; m < Data[k].size(); ++m) {

            size_t div = lround(Data[k][m].GetXScale()/Data.GetXScale());
            size_t div2 = SPR/div;		  // TODO: avoid using hdr->SPR

            // fprintf(stdout,"k,m,div,div2: %i,%i,%i,%i\n",(int)k,(int)m,(int)div,(int)div2);  //
            for (n=0; n < Data[k][m].size(); ++n) {
                uint64_t val;
                double d = Data[k][m][n];
#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__APPLE__)
                val = htole64(*(uint64_t*)&d);
#else
                val = *(uint64_t*)&d;
#endif
                size_t p, spr = (len + n*div) / SPR;

                for (p=0; p < div2; p++)
                   *(uint64_t*)(rawdata + bi + bpb * spr + p*8) = val;
            }
            len += div*Data[k][m].size();
        }
		bi += chSPR*8;
    }

#ifndef DONOTUSE_DYNAMIC_ALLOCATION_FOR_CHANSPR
	if (chanSPR) free(chanSPR);
#endif

    /******************************
        write to file
    *******************************/
    std::string errorMsg("Exception while calling std::exportBiosigFile():\n");

    hdr = sopen( fName.c_str(), "w", hdr );
    if (serror2(hdr)) {
        errorMsg += biosig_get_errormsg(hdr);
        destructHDR(hdr);
        throw std::runtime_error(errorMsg.c_str());
        return false;
    }

    ifwrite(rawdata, bpb, NRec, hdr);

    sclose(hdr);
    destructHDR(hdr);
    free(rawdata);


#else   // #ifndef __LIBBIOSIG2_H__


    HDRTYPE* hdr = constructHDR(Data.size(), 0);
    assert(hdr->NS == Data.size());

	/* Initialize all header parameters */
    hdr->TYPE = GDF;
#if (BIOSIG_VERSION >= 10508)
    /* transition in biosig to rename HDR->VERSION to HDR->Version
       to avoid name space conflict with macro VERSION
     */
    hdr->Version = 3.0;   // select latest supported version of GDF format
#else
    hdr->VERSION = 3.0;   // select latest supported version of GDF format
#endif

    struct tm t = Data.GetDateTime();

    hdr->T0 = tm_time2gdf_time(&t);

    const char *xunits = Data.GetXUnits().c_str();
#if (BIOSIG_VERSION_MAJOR > 0)
    uint16_t pdc = PhysDimCode(xunits);
#else
    uint16_t pdc = PhysDimCode((char*)xunits);
#endif
    if ((pdc & 0xffe0) == PhysDimCode("s")) {
        fprintf(stderr,"Stimfit exportBiosigFile: xunits [%s] has not proper units, assume [ms]\n",Data.GetXUnits().c_str());
        pdc = PhysDimCode("ms");
    }
    hdr->SampleRate = 1.0/(PhysDimScale(pdc) * Data.GetXScale());
    hdr->SPR  = 1;

    hdr->FLAG.UCAL = 0;
    hdr->FLAG.OVERFLOWDETECTION = 0;

    hdr->FILE.COMPRESSION = 0;

	/* Initialize all channel parameters */
    size_t k, m;
    for (k = 0; k < hdr->NS; ++k) {
        CHANNEL_TYPE *hc = hdr->CHANNEL+k;

        hc->PhysMin = -1e9;
        hc->PhysMax =  1e9;
        hc->DigMin  = -1e9;
        hc->DigMax  =  1e9;
        hc->Cal     =  1.0;
        hc->Off     =  0.0;

        /* Channel descriptions. */
        strncpy(hc->Label, Data[k].GetChannelName().c_str(), MAX_LENGTH_LABEL);
#if (BIOSIG_VERSION_MAJOR > 0)
        hc->PhysDimCode = PhysDimCode(Data[k].GetYUnits().c_str());
#else
        hc->PhysDimCode = PhysDimCode((char*)Data[k].GetYUnits().c_str());
#endif
        hc->OnOff      = 1;
        hc->LeadIdCode = 0;

        hc->TOffset  = 0.0;
        hc->Notch    = NAN;
        hc->LowPass  = NAN;
        hc->HighPass = NAN;
        hc->Impedance= NAN;

        hc->SPR    = hdr->SPR;
        hc->GDFTYP = 17; 	// double

        // each segment gets one marker, roughly
        hdr->EVENT.N += Data[k].size();

        size_t m,len = 0;
        for (len=0, m = 0; m < Data[k].size(); ++m) {
            unsigned div = lround(Data[k][m].GetXScale()/Data.GetXScale());
            hc->SPR = lcm(hc->SPR,div);  // sampling interval of m-th segment in k-th channel
            len += div*Data[k][m].size();
        }
        hdr->SPR = lcm(hdr->SPR, hc->SPR);

        if (k==0) {
            hdr->NRec = len;
        }
        else if ((size_t)hdr->NRec != len) {
            destructHDR(hdr);
            throw std::runtime_error("File can't be exported:\n"
                "No data or traces have different sizes" );

            return false;
        }
    }

    hdr->AS.bpb = 0;
    for (k = 0; k < hdr->NS; ++k) {
        CHANNEL_TYPE *hc = hdr->CHANNEL+k;
        hc->SPR = hdr->SPR / hc->SPR;
        hc->bi  = hdr->AS.bpb;
        hdr->AS.bpb += hc->SPR * 8; /* its always double */
    }

	/***
	    build Event table for storing segment information
	 ***/
	size_t N = hdr->EVENT.N * 2;    // about two events per segment
	hdr->EVENT.POS = (uint32_t*)realloc(hdr->EVENT.POS, N * sizeof(*hdr->EVENT.POS));
	hdr->EVENT.DUR = (uint32_t*)realloc(hdr->EVENT.DUR, N * sizeof(*hdr->EVENT.DUR));
	hdr->EVENT.TYP = (uint16_t*)realloc(hdr->EVENT.TYP, N * sizeof(*hdr->EVENT.TYP));
	hdr->EVENT.CHN = (uint16_t*)realloc(hdr->EVENT.CHN, N * sizeof(*hdr->EVENT.CHN));
#if (BIOSIG_VERSION >= 10500)
	hdr->EVENT.TimeStamp = (gdf_time*)realloc(hdr->EVENT.TimeStamp, N * sizeof(gdf_time));
#endif

    /* check whether all segments have same size */
    {
        char flag = (hdr->NS>0);
        size_t m, POS, pos;
        for (k=0; k < hdr->NS; ++k) {
            pos = Data[k].size();
            if (k==0)
                POS = pos;
            else
                flag &= (POS == pos);
        }
        for (m=0; flag && (m < Data[(size_t)0].size()); ++m) {
            for (k=0; k < hdr->NS; ++k) {
                pos = Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale());
                if (k==0)
                    POS = pos;
                else
                    flag &= (POS == pos);
            }
        }
        if (!flag) {
            destructHDR(hdr);
            throw std::runtime_error(
                    "File can't be exported:\n"
                    "Traces have different sizes or no channels found"
            );
            return false;
        }
    }

        N=0;
        k=0;
        size_t pos = 0;
        for (m=0; m < (Data[k].size()); ++m) {
            if (pos > 0) {
                // start of new segment after break
                hdr->EVENT.POS[N] = pos;
                hdr->EVENT.TYP[N] = 0x7ffe;
                hdr->EVENT.CHN[N] = 0;
                hdr->EVENT.DUR[N] = 0;
                N++;
            }
#if 0
            // event description
            hdr->EVENT.POS[N] = pos;
            FreeTextEvent(hdr, N, "myevent");
            //FreeTextEvent(hdr, N, Data[k][m].GetSectionDescription().c_str()); // TODO
            hdr->EVENT.CHN[N] = k;
            hdr->EVENT.DUR[N] = 0;
            N++;
#endif
            pos += Data[k][m].size() * lround(Data[k][m].GetXScale()/Data.GetXScale());
        }

        hdr->EVENT.N = N;
        hdr->EVENT.SampleRate = hdr->SampleRate;

        sort_eventtable(hdr);

	/* convert data into GDF rawdata from  */
	hdr->AS.rawdata = (uint8_t*)realloc(hdr->AS.rawdata, hdr->AS.bpb*hdr->NRec);
	for (k=0; k < hdr->NS; ++k) {
        CHANNEL_TYPE *hc = hdr->CHANNEL+k;

        size_t m,n,len=0;
        for (m=0; m < Data[k].size(); ++m) {
            size_t div = lround(Data[k][m].GetXScale()/Data.GetXScale());
            size_t div2 = hdr->SPR/div;

            // fprintf(stdout,"k,m,div,div2: %i,%i,%i,%i\n",(int)k,(int)m,(int)div,(int)div2);  //
            for (n=0; n < Data[k][m].size(); ++n) {
                uint64_t val;
                double d = Data[k][m][n];
#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__APPLE__)
                val = htole64(*(uint64_t*)&d);
#else
                val = *(uint64_t*)&d;
#endif
                size_t p, spr = (len + n*div) / hdr->SPR;
                for (p=0; p < div2; p++)
                   *(uint64_t*)(hdr->AS.rawdata + hc->bi + hdr->AS.bpb * spr + p*8) = val;
            }
            len += div*Data[k][m].size();
        }
    }

    /******************************
        write to file
    *******************************/
    std::string errorMsg("Exception while calling std::exportBiosigFile():\n");

    hdr = sopen( fName.c_str(), "w", hdr );
#if (BIOSIG_VERSION > 10400)
    if (serror2(hdr)) {
        errorMsg += hdr->AS.B4C_ERRMSG;
#else
    if (serror()) {
	    errorMsg += B4C_ERRMSG;
#endif
        destructHDR(hdr);
        throw std::runtime_error(errorMsg.c_str());
        return false;
    }

    ifwrite(hdr->AS.rawdata, hdr->AS.bpb, hdr->NRec, hdr);

    sclose(hdr);
    destructHDR(hdr);
#endif

    return true;
}
Example #6
0
/*
 * Write a file.
 */
void
wop(bool dofname)
/* bool dofname;	/ * if 1 call filename, else use savedfile */
{
	register int c, exclam, nonexist;
	line *saddr1, *saddr2;
	struct stat stbuf;
#ifdef	FLOCKFILE
	int *lp, *iop ;
#endif

	c = 0;
	exclam = 0;
	saddr1=addr1;
	saddr2=addr2;
	if (dofname) {
		if (peekchar() == '!')
			exclam++, ignchar();
		ignore(skipwh());
		while (peekchar() == '>')
			ignchar(), c++, ignore(skipwh());
		if (c != 0 && c != 2)
			error("Write forms are 'w' and 'w>>'");
		filename('w');
	} else {
		if (savedfile[0] == 0)
			error("No file|No current filename");
		addr1=one;
		addr2=dol;
		CP(file, savedfile);
		if (inopen) {
			vclrech(0);
			splitw++;
		}
		lprintf("\"%s\"", file);
	}
	nonexist = stat(file, &stbuf);
#ifdef	FLOCKFILE
	/*
	 * if this is either the saved or alternate file or current file,
	 * point to the appropriate descriptor and file lock status.
	 */
	if (strcmp (file,savedfile) == 0) {
		lp = &lock_savedfile ;	iop = &io_savedfile ;
	} else if (strcmp (file,altfile) == 0) {
		lp = &lock_altfile ;	iop = &io_altfile ;
	} else {
		lp = &lock_curr ;	iop = &io_curr ;
	}
	if (!*iop && !nonexist){
		*lp = 0 ;
		if ((*iop = open(file, O_WRONLY)) < 0) *iop = 0 ;
	}
#endif
	switch (c) {

	case 0:
		if (!exclam && (!value(WRITEANY) || value(READONLY)))
		switch (edfile()) {
		
		case NOTEDF:
			if (nonexist)
				break;
			if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
				if (samei(&stbuf, _PATH_DEVNULL))
					break;
				if (samei(&stbuf, _PATH_TTY))
					break;
			}
			io = open(file, O_WRONLY);
			if (io < 0)
				syserror();
			if (!isatty(io))
				serror(" File exists| File exists - use \"w! %s\" to overwrite", file);
			close(io);
			break;

		case EDF:
			if (value(READONLY))
				error(" File is read only");
			break;

		case PARTBUF:
			if (value(READONLY))
				error(" File is read only");
			error(" Use \"w!\" to write partial buffer");
		}
cre:
/*
		synctmp();
*/
#ifdef	FLOCKFILE
	if (*iop && !*lp != LOCK_EX && !exclam) {
		/*
		 * upgrade to a exclusive lock. if can't get, someone else 
		 * has the exclusive lock. bitch to the user.
		 */
		if (flock(*iop, LOCK_EX|LOCK_NB) < 0 && errno == EWOULDBLOCK)
	error (" File being modified by another process - use \"w!\" to write");
		 else *lp = LOCK_EX ;
	}
#endif
#ifdef V6
		io = creat(file, 0644);
#else
		io = creat(file, 0666);
#ifdef vms	/* to retain file protection modes on newer version of file */
		if (!nonexist)
			chmod(file, stbuf.st_mode & 0777);
#endif
#endif
		if (io < 0)
			syserror();
		writing = 1;
		if (hush == 0) {
			if (nonexist)
				ex_printf(" [New file]");
			else if (value(WRITEANY) && edfile() != EDF)
				ex_printf(" [Existing file]");
		}
#ifdef	FLOCKFILE
		if (!*iop)
			*iop = dup(io) ;
#endif
		break;

	case 2:
		io = open(file, O_WRONLY);
		if (io < 0) {
			if (exclam || value(WRITEANY))
				goto cre;
			syserror();
		}
		lseek(io, 0l, SEEK_END);
#ifdef	FLOCKFILE
		if (!*iop) *iop = dup(io) ;
		if (*lp != LOCK_EX && !exclam) {
			/*
		 	 * upgrade to a exclusive lock. if can't get,
			 * someone else has the exclusive lock.
			 * bitch to the user.
		 	 */
			if (flock(*iop, LOCK_SH|LOCK_NB) < 0
			&& errno == EWOULDBLOCK)
				error (
" File being modified by another process - use \"w!>>\" to write");
		 	else *lp = LOCK_EX ;
		}
#endif
		break;
	}
#ifdef	FLOCKFILE
	if (flock(*iop, LOCK_EX|LOCK_NB) >= 0)
		*lp = LOCK_EX ;
#endif
	putfile(0);
#ifndef	vms
	(void) fsync(io);
#endif
	ignore(iostats());
	if (c != 2 && addr1 == one && addr2 == dol) {
		if (eq(file, savedfile))
			edited = 1;
		ex_sync();
	}
	if (!dofname) {
		addr1 = saddr1;
		addr2 = saddr2;
	}
	writing = 0;
}
Example #7
0
File: pqing.c Project: khallock/LDM
int
main(int ac, char *av[])
{
        int logfd;
        int width;
        int ready;
        unsigned long idle;
        fd_set readfds;
        fd_set exceptfds;
        struct timeval timeo;
        const char* const progname = ubasename(av[0]);
        unsigned logopts = LOG_CONS|LOG_PID;
        int logmask = LOG_UPTO(LOG_NOTICE);
        unsigned long maxProductSize = DEFAULT_MAX_PRODUCT_SIZE;

        /*
         * Setup default logging before anything else.
         */
        logfd = openulog(progname, logopts, LOG_LDM, logpath);
        (void) setulogmask(logmask);

        feedtype = whatami(av[0]);

        {
            extern int optind;
            extern int opterr;
            extern char *optarg;
            int ch;

            opterr = 0; /* stops getopt() from printing to stderr */
            usePil = 1;
            useNex = 1;
            pqpath = getQueuePath();

            while ((ch = getopt(ac, av, ":vxcni5Nl:b:p:P:T:q:r:f:s:")) != EOF)
                    switch (ch) {
                    case 'v':
                            logmask |= LOG_MASK(LOG_INFO);
                            (void) setulogmask(logmask);
                            break;
                    case 'x':
                            logmask |= LOG_MASK(LOG_DEBUG);
                            (void) setulogmask(logmask);
                            break;
                    case 'c':
                            chkflag = CHK_CHECK;
                            break;
                    case 'n':
                            chkflag = CHK_DONT;
                            break;
                    case 'i':
                            usePil = 0;
                            break;
                    case 'N':
                            useNex = 0;
                            break;
                    case '5':
                            skipLeadingCtlString = 0;
                            break;
                    case 'l': {
                            logpath = optarg;
                            if (strcmp(logpath, "-") == 0) {
                                logopts = LOG_NOTIME;
                            }
                            else {
                                logopts = LOG_CONS | LOG_PID;
                                (void) fclose(stderr);
                            }
                            logfd = openulog(progname, logopts, LOG_LDM, logpath);
                            break;
                    }
                    case 'b':
                            baud = optarg;
                            break;
                    case 'p':
                            parity = optarg;
                            break;
    #if NET
                    case 'P':
                            *((int *)&server_port) = atoi(optarg); /* cast away const */
                            if(server_port <= 0 || server_port > 65536)
                            {
                                    LOG_ADD1("Invalid server port: \"%s\"", optarg);
                                    log_log(LOG_ERR);
                                    usage(progname);
                            }
                            break;
                    case 'T':
                            reset_secs = atoi(optarg);
                            if(reset_secs < 0)
                            {
                                    LOG_ADD1("Invalid timeout: \"%s\"", optarg);
                                    usage(progname);
                            }
                            break;
    #endif /* NET */
                    case 's': {
                            unsigned long size;
                            int           nbytes;

                            if (sscanf(optarg, "%lu %n", &size, &nbytes) != 1 ||
                                    optarg[nbytes] != 0 || 1 > size) {
                                LOG_ADD1("Invalid maximum data-product size: \"%s\"",
                                        optarg);
                                log_log(LOG_ERR);
                                usage(progname);
                            }

                            maxProductSize = size;
                            break;
                    }
                    case 'q':
                            pqpath = optarg;
                            break;
                    case 'r':
                            rawfname = optarg;
                            break;
                    case 'f':
                            {
                                    feedtypet type;
                                    type = atofeedtypet(optarg);
                                    if(type != NONE)
                                    {
                                            feedtype = type;
                                            if(!parity && !baud)
                                                    setFeedDefaults(type);
                                    }
                            }
                            break;
                    case '?': {
                            LOG_ADD1("Unknown option: \"%c\"", optopt);
                            usage(progname);
                            break;
                    }
                    case ':':
                    /*FALLTHROUGH*/
                    default:
                            LOG_ADD1("Missing argument for option: \"%c\"", optopt);
                            usage(progname);
                            break;
                    }

            /* last arg, feedfname, is required */
            if(ac - optind != 1) {
                    LOG_ADD1("Wrong number of operands: %d", ac - optind);
                    usage(progname);
            }
            (void)strncat(feedfname, av[optind], sizeof(feedfname)-6);
        }

        unotice("Starting Up");
        udebug(PACKAGE_VERSION);

        if(logpath == NULL || !(*logpath == '-' && logpath[1] == 0))
        {
                if (logfd < 0) {
                    uerror("logfd < 0");
                    return 1;
                }
                setbuf(fdopen(logfd, "a"), NULL);
        }       

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                return 1;
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        /*
         * open the product queue, unless we were invoked as "feedtest"
         */
        if(strcmp(progname, "feedtest") != 0)
        {
                if((ready = pq_open(pqpath, PQ_DEFAULT, &pq)))
                {
                        if (PQ_CORRUPT == ready) {
                            uerror("The product-queue \"%s\" is inconsistent\n",
                                    pqpath);
                        }
                        else {
                            uerror("pq_open: \"%s\" failed: %s",
                                    pqpath, strerror(ready));
                        }
                        return 1;
                }
        }

        /*
         * who am i, anyway
         */
        (void) strncpy(myname, ghostname(), sizeof(myname));
        myname[sizeof(myname)-1] = 0;

        /*
         * open the feed
         */
        if(!(*feedfname == '-' && feedfname[1] == 0) && logfd != 0)
                (void) close(0);

        if(open_feed(feedfname, &ifd, maxProductSize) != ENOERR)
                return 1;

        if(usePil == 1)
           {
           if ((feedtype & DDS)||(feedtype & PPS)||(feedtype & IDS)||
                (feedtype & HRS))
              {
              usePil = 1;
              uinfo("Creating AFOS-like pil tags\0");
              }
           else
              {
              usePil = 0;
              }
           }

        if (feedtype & HDS)
        {
                if(chkflag == CHK_CHECK
                                || (isatty(ifd) && chkflag != CHK_DONT))
                        setTheScanner(scan_wmo_binary_crc);
                else
                        setTheScanner(scan_wmo_binary);
        }
        else if (feedtype == ( DDPLUS | IDS ) ) 
        { 
                /* this is the combined NOAAPORT fos-alike. We know these have the
                   4 byte start and end sequences. Using the binary scanner
                   ensures that we don't stop on an arbitray embedded CTRL-C */
                unotice("Note: Using the wmo_binary scanner for SDI ingest\0");
                setTheScanner (scan_wmo_binary); 
        }
        else if (feedtype & (NMC2 | NMC3))
        {
                setTheScanner(scan_wmo_binary);
        }
        else if (feedtype == AFOS)
        {
                prod_stats = afos_stats;
                setTheScanner(scan_afos);
        }
        else if (feedtype == FAA604)
        {
                prod_stats = faa604_stats;
                if(chkflag == CHK_CHECK
                        || (isatty(ifd)
                                 && chkflag != CHK_DONT
                                 && parity != NULL
                                 && *parity != 'n')
                        )
                {
                        setTheScanner(scan_faa604_parity);
                }
                else
                {
                        setTheScanner(scan_faa604);
                }
        }
        else
        {
                if(chkflag == CHK_CHECK
                        || (isatty(ifd)
                                 && chkflag != CHK_DONT
                                 && parity != NULL
                                 && *parity != 'n')
                        )
                {
                        setTheScanner(scan_wmo_parity);
                }
                else
                {
                        setTheScanner(scan_wmo);
                }
        }

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                serror("new_md5_CTX failed");
                return 1;
        }


        /*
         * Main Loop
         */
        idle = 0;
        while(exitIfDone(0))
        {
#if NET
if (INPUT_IS_SOCKET)
{
                if (port_error)
                {
                        /*
                         * lost connection => close
                         */
                        if (ifd >= 0)
                        {
                                if(feed_close)
                                        (*feed_close)(ifd);
                                ifd = -1;
                        }
                        port_error = 0;
                        sleep (2);      /* allow things to settle down */
                        continue;
                }
}
#endif
                if(stats_req)
                {
                        unotice("Statistics Request"); 
                        if(pq != NULL)
                        {
                                off_t highwater = 0;
                                size_t maxregions = 0;
                                (void) pq_highwater(pq, &highwater,
                                         &maxregions);
                                unotice("  Queue usage (bytes):%8ld",
                                                        (long)highwater);
                                unotice("           (nregions):%8ld",
                                                        (long)maxregions);
                        }
                        unotice("       Idle: %8lu seconds", idle);
#if NET
if (INPUT_IS_SOCKET)
{
                        unotice("    Timeout: %8d", reset_secs);
}
#endif
                        unotice("%21s: %s", "Status",
                                (ifd < 0) ?
                                "Not connected or input not open." :
                                "Connected.");
                        (*prod_stats)();
                        (*feed_stats)();
                        stats_req = 0;
                }
#if NET
if (INPUT_IS_SOCKET)
{
                if (ifd < 0)
                {
                        /* Attempt reconnect */
                        static int retries = 0;
                        if (retries > MAX_RETRIES)
                        {
                                uerror ("maximum retry attempts %d, aborting",
                                        MAX_RETRIES);
                                done = !0;
                                continue;
                        }
                        /* Try to reopen on tcp read errors */
                        unotice("Trying to re-open connection on port %d", 
                                server_port);
                        ++retries;
                        if(open_feed(feedfname, &ifd, maxProductSize) != ENOERR)
                        {
                                unotice ("sleeping %d seconds before retry %d",
                                         retries * RETRY_DELAY, retries+1);
                                sleep (retries * RETRY_DELAY);
                                continue;
                        }
                        retries = 0;
                }
}
#endif /* NET */
                timeo.tv_sec = 3;
                timeo.tv_usec = 0;
                FD_ZERO(&readfds);
                FD_ZERO(&exceptfds);
                FD_SET(ifd, &readfds);
                FD_SET(ifd, &exceptfds);
                width =  ifd + 1;
                ready = select(width, &readfds, 0, &exceptfds, &timeo);
                if(ready < 0 )
                {
                        /* handle EINTR as a special case */
                        if(errno == EINTR)
                        {
                                errno = 0;
                                continue;
                        }
                        serror("select");
                        return 1;
                }
                /* else */
#if 0
                if (FD_ISSET(ifd, &exceptfds))
                {
                        uerror("Exception on input fd %d, select returned %d",
                               ifd, ready);
                }
#endif
                if(ready > 0)
                {
                        /* do some work */
                        if(FD_ISSET(ifd, &readfds) || 
                           FD_ISSET(ifd, &exceptfds))
                        {
                                idle = 0;
                                if(feedTheXbuf(ifd) != ENOERR)
                                {
#if NET
if (INPUT_IS_SOCKET)
{
                                        port_error = !0;
                                        continue;
}                                       /* else */
#endif /* NET */
                                        done = !0;
                                }
                                FD_CLR(ifd, &readfds);
                                FD_CLR(ifd, &exceptfds);
                        }
                        else
                        {
                                uerror("select returned %d but ifd not set",
                                        ready);
                                idle += timeo.tv_sec;
                        }
                }
                else    /* ready == 0 */
                {
                        idle += timeo.tv_sec;
#if NET
if (INPUT_IS_SOCKET)
{
                        /* VOODOO
                         * This is necessary to stimulate
                         * 'Connection reset by peer'
                         * when the Portmaster goes down and comes
                         * back up.
                         */
                        static char zed[1] = {0};
                        if(write(ifd, zed, sizeof(zed)) < 0)
                        {
                                port_error = !0;
                                continue;
                        }

}
#endif
                }
#if NET
if (INPUT_IS_SOCKET)
{
                if ((reset_secs > 0) && (idle >= reset_secs))
                {
                        unotice("Idle for %ld seconds, reconnecting",
                                idle);
                        /* force reconnect */
                        port_error = !0;
                        idle = 0;
                        continue;
                }
}
#endif /* NET */
                (void) scanTheXbuf();
        }

        return 0;
}
Example #8
0
/*
 * Returns:
 *      0       Success.  Write-count of product-queue is zero.
 *      1       System failure.  See error-message.
 *      2       Product-queue doesn't support a writer-counter.  Not possible
 *              if "-F" option used.
 *      3       Write-count of product-queue is greater than zero.  Not possible
 *              if "-F" option used.
 *      4       The product-queue is internally inconsistent.
 */
int main(int ac, char *av[])
{
        const char *progname = ubasename(av[0]);
        char *logfname;
        int status = 0;
        int logoptions = (LOG_CONS|LOG_PID) ;
        unsigned write_count;
        int force = 0;

        logfname = "";

        if(isatty(fileno(stderr)))
        {
                /* set interactive defaults */
                logfname = "-" ;
                logoptions = 0 ;
        }

        {
            extern int opterr;
            extern char *optarg;
            int ch;
            int logmask = (LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) |
                LOG_MASK(LOG_NOTICE));

            opterr = 1;
            pqfname = getQueuePath();

            while ((ch = getopt(ac, av, "Fvxl:q:")) != EOF)
                    switch (ch) {
                    case 'F':
                            force = 1;
                            break;
                    case 'v':
                            logmask |= LOG_MASK(LOG_INFO);
                            break;
                    case 'x':
                            logmask |= LOG_MASK(LOG_DEBUG);
                            break;
                    case 'l':
                            logfname = optarg;
                            break;
                    case 'q':
                            pqfname = optarg;
                            break;
                    case '?':
                            usage(progname);
                            break;
                    }

            (void) setulogmask(logmask);
        }

        /*
         * Set up error logging.
         */
        (void) openulog(progname,
                logoptions, LOG_LDM, logfname);
        unotice("Starting Up (%d)", getpgrp());

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                return 1;
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        if (force) {
            /*
             * Add writer-counter capability to the file, if necessary, and set
             * the writer-counter to zero.
             */
            status = pq_clear_write_count(pqfname);
            if (status) {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent", pqfname);
                    return 4;
                }
                else {
                    uerror("pq_clear_write_count() failure: %s: %s",
                            pqfname, strerror(status));
                    return 1;
                }
            }
            write_count = 0;
        }
        else {
            /*
             * Get the writer-counter of the product-queue.
             */
            status = pq_get_write_count(pqfname, &write_count);
            if (status) {
                if (ENOSYS == status) {
                    uerror("Product-queue \"%s\" doesn't have a writer-counter",
                        pqfname);
                    return 2;
                }
                else if (PQ_CORRUPT == status) {
                    uerror("Product-queue \"%s\" is inconsistent", pqfname);
                    return 4;
                }
                else {
                    uerror("pq_get_write_count() failure: %s: %s",
                        pqfname, strerror(status));
                    return 1;
                }
            }
        }

        uinfo("The writer-counter of the product-queue is %u", write_count);

        return write_count == 0 ? 0 : 3;
}
Example #9
0
double Equillibrium(double &t,Plasma &Gas,Statistics **stats, int nstat){
  struct{
    char s[20];
    double a;
  } RFst[5]= { {"ACCELERATION",0.75},
	       {"ROUGH",1.},
	       {"SCALE",1.5},
	       {"SWITCH OFF", 0.5},
	       {"TEST", 0.25}};

  int j;

  Gas.r0=0.05;
  Gas.init_config(in_cs,in_distr);
  if(mc_equil)MC->initial(Gas);


  double  T_av, dc1,dc2,Estb=0;

  double T_val=Gas.getT();

  int sw_n=10;

  dc2=delta*sqrt(1./Gas.n);

  if(scale_vel)dc1=0.5*sqrt(1./Gas.n);
  else dc1=dc2;

  Statistics *statsl= new Statistics[nstat];
  if(!statsl)fatal_error("Equilibrium: memeory allocation error\n");

  for(j=0;j<nstat;j++){
    statsl[j]=*(stats[j]);
    stats[j]->clear();
  }
  if(write_distr){
    DRRee.clear();
    DRRep.clear();
    if(non_symm)DRRpp.clear();
  }

  int iter=0;
  double Gf1=Gf,Gf0=Gf;

  Gas.ext_force=RandomForce;
  set_regime(ACCEL,dc1,rf_dt0,rf_nsteps);

  do{
    Gas.dt=cur_dt;

    switch(cur_rf){
    case AUTO:
      Gf0=Gf1=1./sqrt(Gas.dt*sqrt((double)Gas.n));
      break;
    case FLUC:
      {
         double dEp=statsl[2].dev()/Gas.n;
         double dEt=statsl[4].dev()/Gas.n;

         if(dEt<1e-10)Gf1*=50.;
         else Gf1=Gf1*sqrt(dEp/dEt);
      }
      break;
    case EXP:
      Gf1=Gf0*(1.-((double)cur_iter)/sw_n);      // exp(-5./sw_n);
      if(Gf1<0.)Gf1=0.;
      break;
    }


    Tr=Gf1*Gf1/(24.);  // adjusting RF and friction
    Efm=Gf1/sqrt(Gas.dt);

    RFstatus=RFst[cur_regime].a;

    if(StopStatus(sfile,0)){
      StopStatus(sfile,-1);
      serror("Program interrupted!\n");
    }

    MoveIt(t,wr_int,cur_nsteps,Gas,stats,statsl,nstat);
    iter++;
    cur_iter++;

    T_av=statsl[0].av();

    if(soft_step && cur_regime<SCALE)Gas.dt=cur_dt*sqrt(1./T_av);


    printf("%s: Average values for %ld steps with RF:\n"
	   "Epot=%f, Ecoul=%f, Temp=%f\n",RFst[cur_regime].s,cur_nsteps,
            statsl[2].av()/Gas.n,statsl[1].av()/Gas.n,T_av);


    if(write_distr)WriteDRR(distrfile);
    if(wr_film)WriteFilm(filmdir,Gas);





    if(fabs(1.-T_val/T_av)>cur_dc){
      if(cur_regime==SCALE){
         if(scale_vel && cur_iter<20){
           Gas.vel_scale(Gas.T/T_av);
           continue;
         }
      }
      if(cur_regime==TEST || cur_regime==SCALE || cur_regime==SWITCH_OFF){
         Gf1=Gf0;

         if(mc_equil){
           if(MC->momentum_depend)Gas.vel_scale(1.);
           MC->initial(Gas);
         }
         else Gas.ext_force=RandomForce;

         set_regime(ROUGH,dc1,rf_dt0,rf_nsteps);
         continue;
      }
    }// continues the cycle
    else{
      if(cur_regime==ACCEL){ // clearing meaningless statistics
          for(j=0;j<nstat;j++)stats[j]->clear();
          if(write_distr){
            DRRee.clear();
            DRRep.clear();
            if(non_symm)DRRpp.clear();
          }
      }

      if(cur_regime<=ROUGH){
         if(scale_vel)Gas.vel_scale(Gas.T/T_av);
         set_regime(SCALE,dc2,rf_dt0,tst_nsteps);
         continue;
      }

      if(cur_regime<=SCALE){
         if(e_stab){
           if(cur_iter<2 ||
	      fabs(Estb-statsl[2].av()/Gas.n)>fabs(Estb)*stab_acc){

             if(cur_iter>=2)printf("Total energy unstability %2.0f%%!\n",
				   100.*fabs(1.-statsl[2].av()/(Estb*Gas.n)));
             else printf("Energy stability check...\n");
	     Estb=statsl[2].av()/Gas.n;
             continue;
           }

         }
         if(rf_sw_off){
           Gf0=Gf1;
           set_regime(SWITCH_OFF,dc1,rf_dt0,sw_nsteps/sw_n);
           continue;
         }
         else if(e_stab){ // catching the average
           printf("Adjusting to average...\n");
           catch_average=1;
           Estab=statsl[2].av();
           MoveIt(t,wr_int,tst_nsteps,Gas,stats,statsl,nstat);
           if(catch_average){
             catch_average=0;
             printf("failed!\n");
             Estb=statsl[2].av()/Gas.n;
             continue;
           }
           else printf("OK\n");
         }

      }
      if(cur_regime==SWITCH_OFF){
			    if(cur_iter<sw_n)continue;
      }
      if(cur_regime<TEST && !no_test){
         Gas.ext_force=void_force1;
         set_regime(TEST,dc2,eq_dt,chk_nsteps);
         continue;
      }
      else break;
    }

   }while(iter<1000);

   if(iter>=1000){
     printf("Cannot reach equillibrium after 1000 cycles !\n");
     return -1.;
   }

   for(j=0;j<nstat;j++){
     *(stats[j])=statsl[j];
   }

   if(write_distr){
     DRRee.clear();
     DRRep.clear();
     if(non_symm)DRRpp.clear();
   }

   RFstatus=0.0;
   delete [] statsl;
   return t;
}
Example #10
0
void LoadFriedemann(char *ctrfile,Plasma &Gas){

  FILE *f1=Err_fopen(ctrfile,"rt");
  char str[800]; //,str1[200];
  int brk=0;
  do{

    if(feof(f1))serror("Can't find Friedemann's data in file %s.\n",ctrfile);
    fscanf(f1,"%s",str);
    if(str[0]=='#')fgets(str,800,f1);
    else brk=1;
  }while(!brk);

  int i,j;
  double val;
  for(i=0;i<12;i++)
    if(!fscanf(f1,"%lf",&val))serror("Bad Friedemann data\n");

  double me=0.9109534e-30;
  double unit_t=(1.602e-19)*(1.602e-19)/(4*M_PI*8.854e-12)*sqrt(me)*pow(1.38e-23*Gas.par_T*1e4,-3./2.);
  printf("unit_t: %e\n",unit_t);
  double ee;
  Vector_3 vav(0,0,0);

  int stat=0;
  do{
    ee=0.;
    vav=Vector_3(0,0,0);

    for(i=0;i<Gas.n;i++){
      for(j=0;j<3;j++){
       fscanf(f1,"%lf",&(Gas.x[i][j]));
       //printf("X %d, %d: %f",i,j,Gas.x[i][j]);
       Gas.x[i][j]*=5.2917655e-11/unit_l;
       Gas.x[i][j]-=Gas.L/2;
       //printf(" - %f %f\n",Gas.x[i][j],Gas.x[i][j]/Gas.L);
      }
      for(j=0;j<3;j++){
       fscanf(f1,"%lf",&(Gas.v[i][j]));
       //ee+=Gas.v[i][j]*Gas.v[i][j];
       //printf("V %d, %d: %f",i,j,Gas.v[i][j]);
       Gas.v[i][j]*=1.9939022e-24/unit_l/me*unit_t;
       ee+=Gas.v[i][j]*Gas.v[i][j];
       vav[j]+=Gas.v[i][j];
       //printf(" - %f\n",Gas.v[i][j]);
      }
      if(feof(f1)){
        serror("Bad Friedemann data: unexpected end-of-file\n");
        break;
      }
    }
    stat=1;
    for(i=0;i<13;i++){
      if(!fscanf(f1,"%lf",&val))break;
    }
  }while(i==13 && !feof(f1));

  vav/=Gas.n;
  printf("Read Friedem: Energy: %f, Vav: (%f, %f, %f) - %f\n", ee/3/Gas.n,vav[0],vav[1],vav[2],vav*vav/3);
  //for(i=0;i<Gas.n;i++)Gas.v[i]*=sqrt(3*Gas.n/ee);

  fclose(f1);
}
Example #11
0
int main(int argc, char *argv[]){



# ifdef UNIX
 static char state[256];
 initstate(1997,state,256);
# else
  Exit_wait(1);
# endif

 Set_comment_char(';');

 StartTime();
 char *cfgfile="Params.dta";
 if(argc>1)cfgfile=argv[1];

 int no_remove=1;
 if(argc>2)if(strstr(argv[2],"new"))no_remove=0;

 Open_param_file(cfgfile);
 int nions,i;


 Read_param("Number of ions: %d",&nions);
 Read_param("Ionisation degree: %d",&i);
 ion_charge=i;

 double imass=1.;
 Set_stop(0);
 if(Read_param("Ion mass: %lf",&imass)){
   printf("Non-symmetric plasma specified!\n");
   non_symm=1;
 }

 char tmpstr[256];

 int sep_cm=0;
 if(Read_param("Center-of-mass for components: %s",tmpstr)){
   if(strstr(tmpstr,"separate")){
     printf("Plasma with separated center of masses specified!\n");
     sep_cm=1;
   }
 }



 Plasma *TheGas;  // allocation of the Gas
 double bdens, bTv;
 int bq;
 int bunch=Read_param("Bunch propagation: %lf, %lf, %d",&bdens,&bTv,&bq);
 if(bunch>0){
   printf("Bunch in plasma specified!\n");
   if(bunch!=3){
     msg_error("Invalid bunch specification!\n");
     exit(1);
   }
   bunch=1;
   bTv=sqrt(3*nions*i*bTv); // converting temperature to velocity
   TheGas=(Plasma *)new PlasmaBunch(bdens,bTv,bq,nions,i,imass);
 }
 else{
   TheGas=new Plasma(nions,i,imass);
   bunch=0;
 }
 Plasma &Gas=*TheGas;

 Gas.non_symm=non_symm;
 Gas.one_center=1-sep_cm;

 char dataname[50];
 Read_param("Data name: %s",dataname);
 strncpy(Gas.dataname,dataname,50);

 char ofile[256], pfile[256]="poten.dat";


 strcat(strcpy(pfile,dataname),".pot");

 Read_param("Output file: %s",ofile);
 if(strstr(ofile,"default")){
   strcpy(ofile,dataname);
   strcat(ofile,".eq");
 }

 Read_param("Log file: %s",logfile);
 if(strstr(logfile,"default")){
   strcpy(logfile,dataname);
   strcat(logfile,".log");
 }



 Parameter *p;
 int np=InitParameters(&p);


 double T,Gamma;

 potspec_t reader;
 reader.read_spec(cfgfile);
 Gas.potential=reader.potential;
 strncpy(Gas.charpot,reader.charpot,50);


 /*
 Read_param("Potential: %s",tmpstr);
 strncpy(Gas.charpot,tmpstr,50);
 if(strstr(tmpstr,"Kelbg"))Gas.potential=PotentialKELBG;
 else if(strstr(tmpstr,"Lennard-Johnes"))Gas.potential=PotentialJONES;
 else if(strstr(tmpstr,"Deutsch"))Gas.potential=PotentialDEUTSCH;
 else if(strstr(tmpstr,"Erf"))Gas.potential=PotentialERF;
 else if(strstr(tmpstr,"Cutoff")){
  if(!strcmp(tmpstr,"Cutoff1")){
    Gas.potential=PotentialCUT1;
  }
  else{
    Gas.potential=PotentialCUT;
    Read_param("Cutoff value*: %lf",&E_cut);
  }
 }
 else if(strstr(tmpstr,"ln")){
  Gas.potential=PotentialLN;
  Read_param("Cutoff value*: %lf",&E_cut);
 }
 else if(strstr(tmpstr,"table")){
  Gas.potential=PotentialTAB;
  Read_param("Potential table file: %s",tmpstr);
  Close_param_file();
  ReadPotential(tmpstr);
  Open_param_file(cfgfile);
 }
 else serror("Unknown potential type specified!\n");


 Read_param("Pauli part: %s",tmpstr);
 if(strstr(tmpstr,"n"))Pauli_part=0;


 double Lambda, Lambda_set;
 Read_param("R0: %s",tmpstr);
 if(strstr(tmpstr,"default"))Lambda_set=0.;
 else Lambda_set=atof(tmpstr);

 double Clam_ep=1.,Clam_ee=1;
 Read_param("e-e R0 coefficient: %lf",&Clam_ee);
 Read_param("e-p R0 coefficient: %lf",&Clam_ep);
 */

 int ask=0;
 Read_param("Dialog: %s",tmpstr);
 if(strstr(tmpstr,"y"))ask=1;

 auto_rf=0;
 Gf=10.;
 Read_param("Random force strength: %s",tmpstr);
 if(strstr(tmpstr,"auto"))auto_rf=1;
 else if(strstr(tmpstr,"fluct"))auto_rf=2;
 if(!sscanf(tmpstr,"%lf",&Gf) && auto_rf==0)serror("Can't read Random force strength\n");



 Read_param("Scale velocities: %s",tmpstr);
 if(strstr(tmpstr,"y"))scale_vel=1;

 Read_param("Delta: %lf",&delta);

 Read_param("Trajectory write interval: %ld",&wr_int);
 if(wr_int<=0)wr_int=-1;

 int new_rec=0;
 long wr_ions=0, wr_enseq=-1;
 Set_stop(0);
 if(Read_param("Ions write interval: %ld",&wr_ions)){
   new_rec=1;
   if(!Read_param("Electrons write sequence: %ld",&wr_enseq))wr_enseq=-1;
 }
 Set_stop(1);


 Read_param("Steps to check equillibrium: %ld",&chk_nsteps);
 Read_param("Steps with random force: %ld",&rf_nsteps);
 Read_param("Check steps with random force: %ld",&tst_nsteps);
 Read_param("Steps in equillibrium: %ld",&eq_nsteps);
 Read_param("Time step in equillibrium: %lf",&eq_dt);

 Read_param("Time step for random force: %lf",&rf_dt0);


 char trfile[256]="trajectory";

 int wr_tr=0;
 Set_stop(0);

 /*int pot_corr=0;
 if(Read_param("Potential correction: %s",tmpstr)){
   if(strstr(tmpstr,"y")){
     pot_corr=1;
     strcat(Gas.charpot," corr.");
   }                                       
 }*/


 if(Read_param("Total energy stability: %lf",&stab_acc))e_stab=1;


 if(Read_param("Positive cutoff: %lf",&E_negcut))neg_cut=1;
 else neg_cut=0;

 if(!Read_param("Random generator *:>",tmpstr))strcpy(tmpstr,"3");
 cList rndlist(tmpstr);

 int nrepeats=1;
 if(!Read_param("Repeats: %d",&nrepeats))nrepeats=1;


 char mdistrfile[256]="r-r.distrib";
 double rr_r0=0., rr_r1=-1.;
 if(Read_param("Write r-r distribution: %s",tmpstr)){
   if(strstr(tmpstr,"y")){
     write_distr=1;
     if(!Read_param("r-r file: %s",mdistrfile)||strstr(mdistrfile,"default")){
       strcpy(mdistrfile,"%s%d.rr");
     }
     if(Read_param("r-r range: %lf, %lf",&rr_r0,&rr_r1)!=2){
       rr_r0=0.;
       rr_r1=-1.;
     }
   }
 }


 if(Read_param("Soft step: %s",tmpstr)){
  if(strstr(tmpstr,"n"))soft_step=0;
 }

 if(Read_param("Soft random force: %s",tmpstr)){
  if(strstr(tmpstr,"y")){
    rf_sw_off=1;
    Set_stop(1);
    Read_param("Switch off steps: %ld",&sw_nsteps);
    Set_stop(0);
  }
  else rf_sw_off=0;
 }

 if(Read_param("Relative step: %s",tmpstr)){
  if(strstr(tmpstr,"y"))rel_step=1;
 }


 if(Read_param("Animation : %s",&tmpstr)){
   if(strstr(tmpstr,"y")){
      if(!Read_param("Film directory: %s",filmdir)||strstr(filmdir,"default")){
       strcpy(filmdir,"film/");
      }
   }
 }

 in_cs=-1.;
 Read_param("Initial cluster size: %lf",&in_cs);

 int restart=0,load_fried=0;
 int new_input=0;
 char inptrj[256];

 if(Read_param("Restart: %s",tmpstr)){
  if(strstr(tmpstr,"y")){
    restart=1;
    if(Read_param("Load Friedemann: %s",tmpstr)){
      if(strstr(tmpstr,"y"))load_fried=1;
    }
    if(Read_param("Input from: %s",inptrj))new_input=1;
  }

 }

 long wtype=0;
 if(Read_param("Trajectory file: %s",&trfile)){
  if(strstr(trfile,"default"))strcpy(trfile,"%s%d.r");



  Set_stop(1);
  wr_tr=1;

  Read_param("In output:>",tmpstr);
  if(strstr(tmpstr,"vel"))wtype|=VEL;
  if(strstr(tmpstr,"coord"))wtype|=COORD;
  if(strstr(tmpstr,"flow"))wtype|=FLOW;
  Set_stop(0);

 }
 else printf("Warning: no trajectory file\n");

 int mc_one=0;
 int mc_diff=0;
 int auto_adjust=1;
 double mc_inistep;

 int no_equilibr=0;
 Set_stop(1);
 if(Read_param("Equilibration procedure: %s",tmpstr)){
   if(strstr(tmpstr,"monte-carlo")){
     Set_stop(1);
     mc_equil=1;
     Read_param("One particle MC-step: %s",tmpstr);
     if(strstr(tmpstr,"y")){
       mc_one=1;
       // rf_dt0/=Gas.n;
     }
     Read_paramn(2,"MC step mode and value: %s %lf",tmpstr, &mc_inistep);
     if(strstr(tmpstr,"auto"))auto_adjust=1;
     else if(strstr(tmpstr,"stable"))auto_adjust=0;
     else serror("Unknown MC step mode.\n");
     Set_stop(0);
     mc_diff=0;
     if(Read_param("MC different temperatures: %s",tmpstr)){
       if(strstr(tmpstr,"y")){
	 if(mc_one)serror("Can use different MC temperatures\n"
			  "only in MC one-particle mode!\n");
	 mc_diff=1;
       }
     }
   }
   else{
     mc_equil=0;
     if(strstr(tmpstr,"off"))no_equilibr=1;
     else if(!strstr(tmpstr,"random-force")){
       serror("Unknown equilibration procedure: %s\n",tmpstr);
     }
   }
 }

 

 Set_stop(0);
 mc_calc=0;
 if(Read_param("Equilibrium calculation: %s",tmpstr)){
   if(strstr(tmpstr,"monte-carlo")){
     Set_stop(1);
     mc_calc=1;
     Read_param("One particle MC-step: %s",tmpstr);
     if(strstr(tmpstr,"y")){
       mc_one=1;
       // rf_dt0/=Gas.n;
     }
     Read_paramn(2,"MC step mode and value: %s %lf",tmpstr, &mc_inistep);
     if(strstr(tmpstr,"auto"))auto_adjust=1;
     else if(strstr(tmpstr,"stable"))auto_adjust=0;
     else serror("Unknown MC step mode.\n");
     Set_stop(0);
     mc_diff=0;
     if(Read_param("MC different temperatures: %s",tmpstr)){
       if(strstr(tmpstr,"y")){
	 if(mc_one)serror("Can use different MC temperatures\n"
			  "only in MC one-particle mode!\n");
	 mc_diff=1;
       }
     }
   }
 }

//# ifdef UNIX

 char out_dirs[250]="./",out_dirl[250]="./";
 if(Read_param("Data output directory: %s",out_dirs)){
   if(out_dirs[strlen(out_dirs)-1]!='/')strcat(out_dirs,"/");
   sprintf(tmpstr,out_dirs,dataname);
   strcpy(out_dirs,tmpstr);
# ifdef UNIX
   if(mkdir(out_dirs,S_IRWXU|S_IRGRP|S_IROTH)){
     if(errno!=EEXIST)serror("Can not create directory: %s.\n%s\n",
			     out_dirs,strerror(errno));
   }
   sprintf(tmpstr,"cp %s %s%s.cfg",cfgfile,out_dirs,dataname);
   //strcat(strcat(tmpstr,dataname),".cfg");
   if(system(tmpstr)==-1)
     printf("\nExec: %s\n",strerror(errno));
# else
   if(_mkdir(out_dirs)){
     if(errno!=EEXIST)serror("Can not create directory: %s.\n%s\n",
			     out_dirs,strerror(errno));
   }
   char cfgfilef[_MAX_PATH], out_dirsf[_MAX_PATH];
   _fullpath(cfgfilef, cfgfile, _MAX_PATH);
   _fullpath(out_dirsf, out_dirs, _MAX_PATH);
   sprintf(tmpstr,"copy %s %s%s.cfg",cfgfilef,out_dirsf,dataname);
   //strcat(strcat(tmpstr,dataname),".cfg");
   if(system(tmpstr)==-1)
     printf("\nExec: %s\n",strerror(errno));
# endif

   


   strcpy(ofile,strcat(strcpy(tmpstr,out_dirs),ofile));
   strcpy(mdistrfile,strcat(strcpy(tmpstr,out_dirs),mdistrfile));
   strcpy(sfile,strcat(strcpy(tmpstr,out_dirs),sfile));
   strcpy(pfile,strcat(strcpy(tmpstr,out_dirs),pfile));
   if(wr_film){
     strcpy(filmdir,strcat(strcpy(tmpstr,out_dirs),ofile));
# ifdef UNIX
     if(mkdir(filmdir,S_IRWXU|S_IRGRP|S_IROTH)){
# else
     if(_mkdir(filmdir)){
# endif
       if(errno!=EEXIST)serror("Can not create directory: %s.\n%s\n",
			       filmdir,strerror(errno) );
     }
     strcat(filmdir,dataname);
   }
 }
 if(Read_param("Process output directory: %s",out_dirl)){
   if(out_dirl[strlen(out_dirl)]!='/')strcat(out_dirl,"/");
   sprintf(tmpstr,out_dirl,dataname);
   strcpy(out_dirl,tmpstr);


# ifdef UNIX
   if(mkdir(out_dirl,S_IRWXU|S_IRGRP|S_IROTH)){
# else
   if(_mkdir(out_dirl)){
# endif 
     if(errno!=EEXIST)serror("Can not create directory: %s.\n%s\n",
			     out_dirl,strerror(errno));
   }


   strcpy(logfile,strcat(strcpy(tmpstr,out_dirl),logfile));
   strcpy(trfile,strcat(strcpy(tmpstr,out_dirl),trfile));
 }

//# endif  // UNIX

 int spwn_trj=0;

 if(Read_param("Spawn trajectories: %s",tmpstr)){
   if(strstr(tmpstr,"y")){
    spwn_trj=1;
    //Read_paramn(1,"Spawn frame: %d",&spwn_frame);
    no_test=1; // no RF test for equilibrartion
   }
 }

 Gas.stable_ions=0;
 if(Read_param("Stable ions: %s",tmpstr)){
   if(strstr(tmpstr,"y")){
    Gas.stable_ions=1;

   }
 }

 int repc_i=0;
 if(!Read_param("Repeat counter start: %d",&repc_i))repc_i=0;

 int irescale=0;
 if(Read_param("Ion velocity rescale: %s",tmpstr)){
  if(strstr(tmpstr,"y"))irescale=1;
  if(strstr(tmpstr,"reset"))irescale=2;
 }

 /*
 int limrescale=0;
 if(Read_param("Rescale on electron temperature reached: %lf  %ld",&limTe,&limstpe)==2){
  limrescale=1;
  limspec=0x2;
  limrescale_switch(0);
 } */

 int limrescale=0;
 int inc_mes=0;

 if(Read_param("Incremental measurement (T0,dT,mes_steps): %lf,%lf,%ld",&incT0,&incdT,&incStp)==3){
   inc_mes=1;
   fixT=incT0;
   limstpe=1;
   limstpi=1;
 }



 Set_stop(1);



 Gas.ini_Te=Gas.ini_Ti=1.;  // by default equal temperatures
 Read_param("Initial velocity distribution: %s",tmpstr);
 if(strstr(tmpstr,"maxwell"))in_distr=MAXWELL;
 else if(strstr(tmpstr,"max_polak"))in_distr=MAXWELL_P;
 else if(strstr(tmpstr,"zero")){
   if(mc_equil){
     in_distr=MAXWELL;
     printf("Warning: setting 'maxwell' initial vel. distribution for MC!\n");
   }
   else in_distr=ZEROVEL;
 }
 else if(strstr(tmpstr,"separate")){
   in_distr=SEPARATE;
   int &ndistr=Gas.idistr;
   int nr;
   char relstr[200];
   for(i=0;i<2;i++){
    if(i==0)nr=  Read_param("Electron velocity distribution: %s  %lf  %s",tmpstr,&Gas.ini_Te,relstr);
    else{
     nr= Read_param("Ion velocity distribution: %s  %lf %s",tmpstr,&Gas.ini_Ti,relstr);
     Gas.edistr=ndistr;
    }
    if(nr<2){
      serror("Can't read velocity distribution parameters!\n");
    }
    if(nr>=2){
      if(strstr(relstr,"abs")){
        if(i==0)Gas.rel_Te=0;
        else Gas.rel_Ti=0;
      }
    }

    if(strstr(tmpstr,"maxwell"))ndistr=MAXWELL;
    else if(strstr(tmpstr,"max_polak"))ndistr=MAXWELL_P;
    else if(strstr(tmpstr,"zero"))ndistr=ZEROVEL;
    else {
     printf("Warning: unknown distribution '%s', setting to 'zero'\n",tmpstr);
     ndistr=ZEROVEL;
    }
   }
 }
 else{
   printf("Warning: unknown distribution '%s', setting to 'zero'\n",tmpstr);
   in_distr=ZEROVEL;
 }

 

 Close_param_file();


 Statistics sT(&Gas.T),sEcoul(&Gas.Ecoul),sEpotent(&Gas.Epotent),sQuant(&Gas.Quant), sEtot(&Gas.Etot);
 Statistics sTi(&Gas.Ti),sTe(&Gas.Te);
 const int nstat=7;
 Statistics *stats[nstat]={&sT,&sEcoul,&sEpotent,&sQuant,&sEtot,&sTi,&sTe};

 SetTableform(GNU);
 if(no_remove){
   no_remove=CheckData(sfile,ofile,dataname,np,p,ask);
 }

 if(restart && !wr_tr && !new_input)serror("No trajectory file specified, cannot restart.\n");
 if(restart && new_input && wr_tr)
   if(!strcmp(trfile,inptrj))
     serror("Equal names for input and output trj-files.\n");


 FILE *f1;
 if(!no_remove || no_remove==2){
  if(!no_remove)f1=Err_fopen(ofile,"wt");
  else f1=Err_fopen(ofile,"at");
  BeginFrame(f1,dataname,np,p);
  fprintf(f1,"%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n",
             "T","Ecoul","Epotent","Equant","dT","dEcoul","dEpotent","dEquant");
  fclose(f1);
 }

 double t=0;

 f1=fopen(logfile,"rt");
 if(f1){
   if(!restart && !no_remove){
     fclose(f1);
     remove(logfile);
   }
   else {// reading 'log' time
     fseek(f1,0,SEEK_END);
     long pos=ftell(f1)-4;
     do{
       fseek(f1,pos,SEEK_SET);
       if(fgetc(f1)=='\n'){
	        fscanf(f1,"%lf",&t);
         //printf("new t: %f\n",t);
	        break;
       }
       pos--;
     }while(pos>=0);
     fclose(f1);
   }
 }


 int ccount=CurrentCount(np,p);
 WriteStatus(!ccount,sfile,dataname,np,p);



 do{

   //Gamma=get_pc(p[0]);
   //T=get_pc(p[1]);



  char ctrfile[256];
  sprintf(ctrfile,trfile,dataname,ccount);
  char ss[100];
  sprintf(ss,"%s%d",dataname,ccount);
  sprintf(distrfile,mdistrfile,dataname,ccount);

  // StatusLine(str,np,p);
  //show_status(440,str);

  long i,n,m,nf=0;

  //Gas.adjustTG(T,Gamma);

  AdjustGas(Gas,p,np);
  T=Gas.par_T;
  Gamma=Gas.par_Gamma;

  double me=0.9109534e-30;
  double qe=1.602e-19;
  double Kb=1.38e-23;
  double unit_t=qe*qe/(4*M_PI*8.854e-12)*sqrt(me);


  // overcoming g++ bug with -O3
  double jojo=Kb*T*1.e4;
  //printf("c2: %e\n",jojo);
  jojo=jojo*jojo*jojo;
  jojo=sqrt(jojo);
  //printf("c21: %e\n",jojo);
  unit_t/=jojo;
  //printf("c3:\n");

  double unit_h=Kb*T*1e4*unit_t;
  double h_qwer=1.0545887e-34;

  reader.calc_lambda(T,Gas.ini_Te,Gas.ini_Ti,Gas.mass);

  /*
  if(!non_symm){
   if(Lambda_set!=0.0){
     Lambda=Lambda_set/unit_l;
     equal_lambda=0;
   }
   else {
     Lambda=0.179*sqrt(T);
     equal_lambda=1;
   }
   Lambda_pauli=0.179*sqrt(T);
   //non_symm=0;
   Lambda_ee=Lambda_pp=Lambda*Clam_ee;
   if(fabs(Clam_ee-1.)>1e-5)equal_lambda=0;
   Lambda_ep=Lambda*Clam_ep;
  }
  else{
   if(Lambda_set!=0.0){
     serror("Can not setup lambda for nonsymmetric plasma.\n");
     //Lambda=Lambda_set/unit_l;
     //Lambda_ep=Lambda*Clam_ep;
     //Lambda_ee=Lambda*Clam_ee;
     //equal_lambda=0;
   }
   else{
     if(strstr(Gas.charpot,"Deutsch")){
       printf("Setting lambda values for Deutsch potential !!!\n");
       Lambda_pauli=h_qwer/(unit_h);
       Lambda=Lambda_pauli/sqrt(2*M_PI);
       double m_ee=0.5, m_pp=0.5*Gas.mass, m_ep=Gas.mass/(1.+Gas.mass);

       Lambda_ee=Lambda/sqrt(m_ee);
       Lambda_pp=Lambda/sqrt(m_pp);
       Lambda_ep=Lambda/sqrt(m_ep);
     }
     else { //if(strstr(Gas.charpot,"Kelbg")){
       printf("Setting lambda values for Kelbg potential !!!\n");

       Lambda_pauli=h_qwer/(unit_h);
       Lambda=Lambda_pauli;
       double m_ee=0.5, m_pp=0.5*Gas.mass, m_ep=Gas.mass/(1.+Gas.mass);
       double t_ep=Gas.ini_Te;
       double t_pp=Gas.ini_Ti;
       double t_ee=Gas.ini_Te;

       Lambda_ee=Lambda/sqrt(2*m_ee*t_ee);
       Lambda_pp=Lambda/sqrt(2*m_pp*t_pp);
       Lambda_ep=Lambda/sqrt(2*m_ep*t_ep);
     }

   }
  } */


  if(rel_step)rf_dtcoeff=1./Gas.Wpe;

  double kk=(1.602e-19)*(1.602e-19)/(4*M_PI*1.38e-23*T*1e4*8.854e-12);



  printf("Simulation parameters:\n");
  printf("Gamma =%f\n"
	 "L=%f=%12e m\n"
	 "lambda=%f=%12e m\n"
	 "1/Wp=%f\n"
	 "Rd=%f\n",Gamma,Gas.L, Gas.L*kk,reader.Lambda,reader.Lambda*kk,1./Gas.Wpe,RDebye);
  printf("Density = %1.2e cm^(-3)\n"
	 "T= %f K\n",Gas.par_density*1e19,T*1e4);

  printf("Time step relations:\n");
  printf("dtrf*Wp= %f, dteq*Wp= %f\n", (rel_step ? rf_dt0 : rf_dt0*Gas.Wpe),
	 (rel_step ? eq_dt : eq_dt*Gas.Wpe));


  double t_inter=RDebye/sqrt(2*getEmax(Gas));


  printf("dtrf/tint= %f, dteq/tint= %f\n", rf_dt0*rf_dtcoeff/t_inter,
	 eq_dt*rf_dtcoeff/t_inter);


  reader.calc_correction(Gas.par_T);
  reader.write_pot(pfile, Gas.L);

  /*
  //if(ccount==1)t/=Gas.Wpe;
  if(pot_corr){
    //Correction(IONION,Gas.potential,Gas.par_T);
    Correction(IONELC,Gas.potential,Gas.par_T);
    Correction(ELCELC,Gas.potential,Gas.par_T);
  }*/

  Statistics rs[nstat];



  int repi=0;
  int repc=repc_i;

  do{ //through nrepeats

    printf("\nStarting calculation #%d...\n",repc);
    flm_count=0;

    if(repc>0){
      repi++;
      sprintf(tmpstr,"%02d",repc);
      if(repi>1){
       distrfile[strlen(distrfile)-2]=0;
       ctrfile[strlen(ctrfile)-2]=0;
      }
      strcat(distrfile,tmpstr);
      strcat(ctrfile,tmpstr);
    }


    if(write_distr){
      DRRee.init(rr_r0,(rr_r1>0 ? rr_r1 : Gas.L/2),400);
      DRRep.init(rr_r0,(rr_r1>0 ? rr_r1 : Gas.L/2),400);
      if(non_symm)DRRpp.init(0,(rr_r1>0 ? rr_r1 : Gas.L/2),400);
    }

    long ftype=wtype;


    if(restart){
      printf("restarting...\n");
      if((mc_equil && spwn_trj) || mc_calc){
        mc_equil=-1;
        MC = new mc_simm(Gas,mc_inistep*Gas.L /*Gas.L/Gas.n*/,0.5,
			 mc_one,mc_diff);
        if(!MC)serror("Cannot allocate MCsimm\n");
        MC->auto_adjust=auto_adjust;
      }
      else mc_equil=0;

      if(!new_input)strcpy(inptrj,ctrfile);

      if(load_fried){
        LoadFriedemann(inptrj,Gas);
        Gas.dt=eq_dt;
        if(rel_step)Gas.dt/=Gas.Wpe;

        if(eq_nsteps<wr_int)eq_nsteps=wr_int;
	m=wr_int;
	n=eq_nsteps/m;
	Gas.ext_force=void_force1;
	wr_tr=0;
	ftype=0;
      }
      else{
	Gas.dt=(rel_step ? eq_dt/Gas.Wpe : eq_dt);
	Trajectory.Check(inptrj,wtype,Gas,wr_int,wr_ions,wr_enseq,new_input);
	if(Trajectory.wtype !=0 && !new_input){
	  Gas.dt=Trajectory.AdjustInterval(Gas.dt);
	}

	long stp;
	if(!new_input){
	  stp=Trajectory.ReloadGas(Gas,1);
	  t=stp*Trajectory.file_dt();
	  nf=(long)(t/Gas.dt/wr_int+0.01);
	}
	else{
	  stp=Trajectory.ReloadGas(Gas,0);
	  t=0;
	  nf=0;
	}
	printf("t= %f, nf= %ld,  %f\n",t,nf,(t/Gas.dt/wr_int));

	//serror("Restart is not yet implemented !\n");
        Gas.ext_force=void_force1;
      }
      //restart=0;
    }
    else{
      rand_init=rndlist.step();
      if(rand_init<0){
        rndlist.rewind();
        rand_init=rndlist.step();
      }

      strcat(distrfile,"e");


      if((mc_equil && (!spwn_trj || (repc==repc_i && spwn_trj))) || mc_calc){
        mc_equil=1;
        MC = new mc_simm(Gas,mc_inistep*Gas.L /*Gas.L/Gas.n*/,0.5,
			 mc_one,mc_diff);
        if(!MC)serror("Cannot allocate MCsimm\n");
        MC->auto_adjust=auto_adjust;
      }

      if(!no_equilibr){
        if(!spwn_trj || (spwn_trj && repc==repc_i)){
          limrescale_switch(0);
          Equillibrium(t,Gas,stats,nstat);
          limrescale_switch(limrescale);
        }
      }
      else{
        Gas.r0=0.05;
        Gas.init_config(in_cs,in_distr);
      }

      distrfile[strlen(distrfile)-1]=0; // deleting 'e'

      if(mc_equil){
       if(spwn_trj){
        Gas.init_vel(in_distr);
       }
       else if(!mc_calc){
	 delete MC;
	 mc_equil=-1;
       }
       else
         mc_equil=1;
      }

      Gas.dt=eq_dt;
      if(rel_step)Gas.dt/=Gas.Wpe;

    }
    if(irescale){
     if(irescale==1)Gas.ivel_scale(1.);
     else Gas.init_vel(in_distr);
    }

    if(eq_nsteps<wr_int)eq_nsteps=wr_int;
    if(wr_int>0){
      n=eq_nsteps/wr_int;
      m=wr_int;
    }
    else if(eq_nsteps>=500){
      n=eq_nsteps/500;
      m=500;
    }
    else{
      n=1;
      m=eq_nsteps;
    }

    if(wr_tr && (!restart || new_input || (restart && ftype==0))){

      //WriteHeader(ctrfile,wtype,Gas,Gamma,T, ss,m);

      // initializing PlasmaRec
      Trajectory.Clear();
      Trajectory.Init(ctrfile,wtype,Gas,wr_int,wr_ions,wr_enseq);
    }
    if(wr_tr && (restart && ftype==0)){
      //WriteStep(ctrfile,wtype,Gas,0);
    }

    Statistics statsl[nstat];

    Trajectory.valid=wr_tr;
    // new cycle

    if(bunch){
      PlasmaBunch *pb=(PlasmaBunch *)&Gas;
      pb->start_bunch();
    }
    for(i=nf;i<n;i++){
      double term_c=1.;
      if(Gas.stable_ions)term_c=(double)Gas.ne/Gas.n;
      printf("Equilibrium calculation: %f%% complete, T= %f Et=%f\n",(i+1)*100./n,Gas.T,Gas.T*3/2*term_c+Gas.Epotent/Gas.n);

      if(StopStatus(sfile,3)){
       	StopStatus(sfile,-1);
        serror("Program interrupted!\n");
      }

      if(mc_equil && spwn_trj){
        mc_equil=1;
        double ratio=MC->get_ratio();
        if(ratio<1e-10)printf("Estimated randomization steps: infinity\n");
        else printf("Estimated randomization steps: %d\n",(int)(Gas.n*Gas.L/MC->dc[1]/ratio));
      }
      MoveIt(t,m,m,Gas,stats,statsl,nstat);


      //if(wr_tr)WriteStep(ctrfile,wtype,Gas,i);
      if(write_distr)WriteDRR(distrfile);
      if(wr_film)WriteFilm(filmdir,Gas);
    }
    if(bunch){
      PlasmaBunch *pb=(PlasmaBunch *)&Gas;
      pb->stop_bunch();
    }

    if(write_distr)WriteDRR(distrfile);

    for(i=0;i<nstat;i++)rs[i]+=*(stats[i]);
    repc++;

    if(new_input)restart=0;
  }while(repc<nrepeats);

  if(spwn_trj)delete MC;

  f1=Err_fopen(ofile,"at");
  MiddleFrame(f1,np,p);
  int gn=Gas.n;
  //fprintf(f1,"%9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f\n",
  //       sT.av()*T,sEcoul.av()/gn,sEpotent.av()/gn,sQuant.av()/gn,
  //       sT.dev()*T,sEcoul.dev()/gn,sEpotent.dev()/gn,sQuant.dev()/gn);

  fprintf(f1,"%9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f\n",
         rs[0].av()*T,rs[1].av()/gn,rs[2].av()/gn,rs[3].av()/gn,
         rs[0].dev()*T,rs[1].dev()/gn,rs[2].dev()/gn,rs[3].dev()/gn);

  fclose(f1);

  ccount=CycleCount(np,p);
  WriteStatus(!ccount,sfile,dataname,np,p);

  restart=0;
  repc=0;
 }while(ccount);
 return 0;
}
bool DummyUnixSandbox::delete_box() {
    int err = rm_rf(box_base_path(base_path, id_));
    if (err) error(4, serror("Error deleting sandbox", err));
    return !err;
}
DummyUnixSandbox::BoxLocker::~BoxLocker() {
    if (!has_lock_) return;
    if (unlink(lock_name.c_str()) == -1)
        box->warning(4, serror("Error removing lock " + lock_name));
}
Example #14
0
hiya_reply_t*
hiya_6_svc(
        prod_class_t *offered,
        struct svc_req *rqstp)
{
    const char* const pqfname = getQueuePath();
    static hiya_reply_t reply;
    SVCXPRT * const xprt = rqstp->rq_xprt;
    struct sockaddr_in *upAddr = (struct sockaddr_in*) svc_getcaller(xprt);
    const char *upName = hostbyaddr(upAddr);
    int error;
    int isPrimary;
    unsigned int maxHereis;
    static prod_class_t *accept;

    /*
     * Open the product-queue for writing.  It will be closed by cleanup()
     * during process termination.
     */
    if (pq) {
        (void) pq_close(pq);
        pq = NULL;
    }
    error = pq_open(pqfname, PQ_DEFAULT, &pq);
    if (error) {
        err_log_and_free(ERR_NEW2(error, NULL,
                "Couldn't open product-queue \"%s\" for writing: %s",
                pqfname,
                PQ_CORRUPT == error
                ? "The product-queue is inconsistent"
                : strerror(error)), ERR_FAILURE);
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }

    /* else */

    error = down6_init(upName, upAddr, pqfname, pq);
    if (error) {
        uerror("Couldn't initialize downstream LDM");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        uinfo("Downstream LDM initialized");
    }

    /*
     * The previous "accept" is freed here -- rather than freeing the
     * soon-to-be-allocated "accept" at the end of its block -- because it can
     * be used in the reply.
     */
    if (accept) {
        free_prod_class(accept); /* NULL safe */
        accept = NULL;
    }

    error = acl_check_hiya(upName, inet_ntoa(upAddr->sin_addr), offered,
            &accept, &isPrimary);

    maxHereis = isPrimary ? UINT_MAX : 0;

    if (error) {
        serror("Couldn't validate HIYA");
        svcerr_systemerr(xprt);
        svc_destroy(xprt);
        exit(error);
    }
    else {
        if (ulogIsDebug())
            udebug("intersection: %s", s_prod_class(NULL, 0, accept));

        if (accept->psa.psa_len == 0) {
            uwarn("Empty intersection of HIYA offer from %s (%s) and ACCEPT "
                    "entries", upName, s_prod_class(NULL, 0, offered));
            svcerr_weakauth(xprt);
            svc_destroy(xprt);
            exit(0);
        }
        else {
            error = down6_set_prod_class(accept);

            if (error) {
                if (DOWN6_SYSTEM_ERROR == error) {
                    serror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }
                else {
                    uerror("Couldn't set product class: %s",
                            s_prod_class(NULL, 0, accept));
                }

                svcerr_systemerr(xprt);
                svc_destroy(xprt);
                exit(EXIT_FAILURE);
            }

            /* else */

            if (clss_eq(offered, accept)) {
                unotice("hiya6: %s", s_prod_class(NULL, 0, offered));

                reply.code = OK;
                reply.hiya_reply_t_u.max_hereis = maxHereis;
            }
            else {
                if (ulogIsVerbose()) {
                    char off[512];
                    char acc[512];

                    (void) s_prod_class(off, sizeof(off), offered), (void) s_prod_class(
                            acc, sizeof(acc), accept);

                    uinfo("hiya6: RECLASS: %s -> %s", off, acc);
                }

                reply.code = RECLASS;
                reply.hiya_reply_t_u.feedPar.prod_class = accept;
                reply.hiya_reply_t_u.feedPar.max_hereis = maxHereis;
            }
        } /* product-intersection != empty set */
    } /* successful acl_check_hiya() */

    return &reply;
}
Example #15
0
int main(
        int ac,
        char *av[]
)
{
        const char* const       pqfname = getQueuePath();
        const char* const progname = ubasename(av[0]);
        int useProductID = FALSE;
        int signatureFromId = FALSE;
        char *productID = NULL;
        int multipleFiles = FALSE;
        char identifier[KEYSIZE];
        int status;
        int seq_start = 0;
        enum ExitCode {
            exit_success = 0,   /* all files inserted successfully */
            exit_system = 1,    /* operating-system failure */
            exit_pq_open = 2,   /* couldn't open product-queue */
            exit_infile = 3,    /* couldn't process input file */
            exit_dup = 4,       /* input-file already in product-queue */
            exit_md5 = 6        /* couldn't initialize MD5 processing */
        } exitCode = exit_success;

#ifndef HAVE_MMAP
        pqeIndex = PQE_NONE;
#endif

        {
            extern int optind;
            extern int opterr;
            extern char *optarg;
            int ch;

            (void) openulog(progname, LOG_NOTIME, LOG_LDM, "-");
            (void) setulogmask(LOG_UPTO(LOG_NOTICE));

            opterr = 0; /* Suppress getopt(3) error messages */

            while ((ch = getopt(ac, av, ":ivxl:q:f:s:p:")) != EOF)
                    switch (ch) {
                    case 'i':
                            signatureFromId = 1;
                            break;
                    case 'v':
                            (void) setulogmask(getulogmask() | LOG_MASK(LOG_INFO));
                            break;
                    case 'x':
                            (void) setulogmask(getulogmask() | LOG_MASK(LOG_DEBUG));
                            break;
                    case 'l':
                            openulog(progname, ulog_get_options(), LOG_LDM, optarg);
                            break;
                    case 'q':
                            setQueuePath(optarg);
                            break;
                    case 's':
                            seq_start = atoi(optarg);
                            break;
                    case 'f':
                            feedtype = atofeedtypet(optarg);
                            if(feedtype == NONE)
                            {
                                fprintf(stderr, "Unknown feedtype \"%s\"\n", optarg);
                                    usage(progname);
                            }
                            break;
                    case 'p':
                            useProductID = TRUE;
                            productID = optarg;
                            break;
                    case ':': {
                        LOG_ADD1("Option \"-%c\" requires an operand", optopt);
                        usage(progname);
                    }
                    /* no break */
                    default:
                        LOG_ADD1("Unknown option: \"%c\"", optopt);
                        usage(progname);
                        /* no break */
                    }

            ac -= optind; av += optind ;

            if(ac < 1) usage(progname);
            }

        /*
         * register exit handler
         */
        if(atexit(cleanup) != 0)
        {
                serror("atexit");
                exit(exit_system);
        }

        /*
         * set up signal handlers
         */
        set_sigactions();

        /*
         * who am i, anyway
         */
        (void) strncpy(myname, ghostname(), sizeof(myname));
        myname[sizeof(myname)-1] = 0;

        /*
         * open the product queue
         */
        if(status = pq_open(pqfname, PQ_DEFAULT, &pq))
        {
                if (PQ_CORRUPT == status) {
                    uerror("The product-queue \"%s\" is inconsistent\n",
                            pqfname);
                }
                else {
                    uerror("pq_open: \"%s\" failed: %s",
                            pqfname, status > 0 ? strerror(status) :
                                            "Internal error");
                }
                exit(exit_pq_open);
        }


        {
        char *filename;
        int fd;
        struct stat statb;
        product prod;
        MD5_CTX *md5ctxp = NULL;

        /*
         * Allocate an MD5 context
         */
        md5ctxp = new_MD5_CTX();
        if(md5ctxp == NULL)
        {
                serror("new_md5_CTX failed");
                exit(exit_md5);
        }


        /* These members are constant over the loop. */
        prod.info.origin = myname;
        prod.info.feedtype = feedtype;

        if (ac > 1) {
          multipleFiles = TRUE;
        }

        for(prod.info.seqno = seq_start ; ac > 0 ;
                         av++, ac--, prod.info.seqno++)
        {
                filename = *av;

                fd = open(filename, O_RDONLY, 0);
                if(fd == -1)
                {
                        serror("open: %s", filename);
                        exitCode = exit_infile;
                        continue;
                }

                if( fstat(fd, &statb) == -1) 
                {
                        serror("fstat: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                /* Determine what to use for product identifier */
                if (useProductID) 
                  {
                    if (multipleFiles) 
                      {
                        sprintf(identifier,"%s.%d", productID, prod.info.seqno);
                        prod.info.ident = identifier;
                      }
                    else
                      prod.info.ident = productID;
                   }
                else
                    prod.info.ident = filename;
                
                prod.info.sz = statb.st_size;
                prod.data = NULL;

                /* These members, and seqno, vary over the loop. */
                status = set_timestamp(&prod.info.arrival);
                if(status != ENOERR) {
                        serror("set_timestamp: %s, filename");
                        exitCode = exit_infile;
                        continue;
                }

#ifdef HAVE_MMAP
                prod.data = mmap(0, prod.info.sz,
                        PROT_READ, MAP_PRIVATE, fd, 0);
                if(prod.data == NULL)
                {
                        serror("mmap: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : mm_md5(md5ctxp, prod.data, prod.info.sz,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                    serror("mm_md5: %s", filename);
                    (void) munmap(prod.data, prod.info.sz);
                    (void) close(fd);
                    exitCode = exit_infile;
                    continue;
                }

                /* These members, and seqno, vary over the loop. */
                status = set_timestamp(&prod.info.arrival);
                if(status != ENOERR) {
                        serror("set_timestamp: %s, filename");
                        exitCode = exit_infile;
                        continue;
                }

                /*
                 * Do the deed
                 */
                status = pq_insert(pq, &prod);

                switch (status) {
                case ENOERR:
                    /* no error */
                    if(ulogIsVerbose())
                        uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                            ulogIsDebug())) ;
                    break;
                case PQUEUE_DUP:
                    uerror("Product already in queue: %s",
                        s_prod_info(NULL, 0, &prod.info, 1));
                    exitCode = exit_dup;
                    break;
                case PQUEUE_BIG:
                    uerror("Product too big for queue: %s",
                        s_prod_info(NULL, 0, &prod.info, 1));
                    exitCode = exit_infile;
                    break;
                case ENOMEM:
                    uerror("queue full?");
                    exitCode = exit_system;
                    break;  
                case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                case EDEADLOCK:
                    /*FALLTHROUGH*/
#endif
                case EDEADLK:
                    /* TODO: retry ? */
                    /*FALLTHROUGH*/
                default:
                    uerror("pq_insert: %s", status > 0
                        ? strerror(status) : "Internal error");
                    break;
                }

                (void) munmap(prod.data, prod.info.sz);
#else /*HAVE_MMAP*/
                status = 
                    signatureFromId
                        ? mm_md5(md5ctxp, prod.info.ident,
                            strlen(prod.info.ident), prod.info.signature)
                        : fd_md5(md5ctxp, fd, statb.st_size,
                            prod.info.signature);

                (void)exitIfDone(1);

                if (status != 0) {
                        serror("fd_md5: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                if(lseek(fd, 0, SEEK_SET) == (off_t)-1)
                {
                        serror("rewind: %s", filename);
                        (void) close(fd);
                        exitCode = exit_infile;
                        continue;
                }

                index = PQE_NONE;
                status = pqe_new(pq, &prod.info, &prod.data, &index);

                if(status != ENOERR) {
                    serror("pqe_new: %s", filename);
                    exitCode = exit_infile;
                }
                else {
                    ssize_t     nread = read(fd, prod.data, prod.info.sz);

                    (void)exitIfDone(1);

                    if (nread != prod.info.sz) {
                        serror("read %s %u", filename, prod.info.sz);
                        status = EIO;
                    }
                    else {
                        status = pqe_insert(pq, index);
                        index = PQE_NONE;

                        switch (status) {
                        case ENOERR:
                            /* no error */
                            if(ulogIsVerbose())
                                uinfo("%s", s_prod_info(NULL, 0, &prod.info,
                                    ulogIsDebug())) ;
                            break;
                        case PQUEUE_DUP:
                            uerror("Product already in queue: %s",
                                s_prod_info(NULL, 0, &prod.info, 1));
                            exitCode = exit_dup;
                            break;
                        case ENOMEM:
                            uerror("queue full?");
                            break;  
                        case EINTR:
#if defined(EDEADLOCK) && EDEADLOCK != EDEADLK
                        case EDEADLOCK:
                            /*FALLTHROUGH*/
#endif
                        case EDEADLK:
                            /* TODO: retry ? */
                            /*FALLTHROUGH*/
                        default:
                            uerror("pq_insert: %s", status > 0
                                ? strerror(status) : "Internal error");
                        }
                    }                   /* data read into "index" region */

                    if (status != ENOERR) {
                        (void)pqe_discard(pq, index);
                        index = PQE_NONE;
                    }
                }                       /* "index" region allocated */

#endif /*HAVE_MMAP*/
                (void) close(fd);
        }                               /* input-file loop */

        free_MD5_CTX(md5ctxp);  
        }                               /* code block */

        exit(exitCode);
}