//Filename: readabf.cxx //Author: Pamela Y. C. Fong //Maintainer: Qi Huang //PI: Henry A. Lester //Organization: California Institute of Technology // // Reformulated and adapted from API copyrighted // by Axon Instruments, Inc. // //Created: February 12, 2004 //Last Modified: Tue Mar 2 02:02:57 PST 2004 // //Centralize include files in readabf.h #include "xx-abfheadr.h" int main(int argc, char *argv[]) { if(argc != 2) { //Incorrect number of commandline arguments; //Invoke program followed by single filename cout << "usage: readabf filename" << endl; return 1; } //Open the file specified by the commandline argument for binary input ifstream fin(argv[1], ios_base::in | ios_base::binary); if(!fin.is_open()) { //File cannot be opened for binary input cout << "error: cannot open " << argv[1] << " for read"; //Reset failbit fin.clear(); cout << endl; return 1; } //Declare ABFFileHeader structure to hold header information ABFFileHeader *myFH = new ABFFileHeader; //Prepare to read file header into myFH, by positioning the random-access //index to point to the beginning of the file fin.seekg(0, ios_base::beg); //Read the file header into myFH byte-by-byte fin.read((char *) myFH, sizeof *myFH); //Set fHeaderVersion to agree with current version specified by ABFHEADR.H myFH->fHeaderVersionNumber = ABF_CURRENTVERSION; //To format floating point values as fixed decimals, uncomment the next line //cout.setf(ios_base::fixed); //Print out a few parameters cout << "fFileVersionNumber = " << myFH->fFileVersionNumber << "\n"; cout << "nOperationMode = " << myFH->nOperationMode << "\n"; cout << "lActualAcqLength = " << myFH->lActualAcqLength << "\n"; cout << "nNumPointsIgnored = " << myFH->nNumPointsIgnored << "\n"; cout << "lActualEpisodes = " << myFH->lActualEpisodes << "\n"; cout << "lFileStartDate = " << myFH->lFileStartDate << "\n"; cout << "lFileStartTime = " << myFH->lFileStartTime << "\n"; cout << "lStopwatchTime = " << myFH->lStopwatchTime << "\n"; cout << "fHeaderVersionNumber = " << myFH->fHeaderVersionNumber << "\n"; cout << "nFileType = " << myFH->nFileType << "\n"; cout << "nMSBinFormat = " << myFH->nMSBinFormat << "\n"; cout << "lDataSectionPtr = " << myFH->lDataSectionPtr << "\n"; cout << "lTagSectionPtr = " << myFH->lTagSectionPtr << "\n"; cout << "lNumTagEntries = " << myFH->lNumTagEntries << "\n"; cout << "lSynchArrayPtr = " << myFH->lSynchArrayPtr << "\n"; cout << "lSynchArraySize = " << myFH->lSynchArraySize << "\n"; cout << "nDataFormat = " << myFH->nDataFormat << "\n"; cout << "nADCNumChannels = " << myFH->nADCNumChannels << "\n"; cout << "fADCSampleInterval = " << myFH->fADCSampleInterval << "\n"; cout << "fADCSecondSampleInterval = " << myFH->fADCSecondSampleInterval << "\n"; cout << "lClockChange = " << myFH->lClockChange << "\n"; cout << "fADCRange = " << myFH->fADCRange << "\n"; cout << "lADCResolution = " << myFH->lADCResolution << "\n"; cout << "fADCProgrammableGain[0] = " << myFH->fADCProgrammableGain[0] << "\n"; cout << "fInstrumentScaleFactor[0] = " << myFH->fInstrumentScaleFactor[0] << "\n"; cout << "fInstrumentOffset[0] = " << myFH->fInstrumentOffset[0] << "\n"; cout << "fSignalGain[0] = " << myFH->fSignalGain[0] << "\n"; cout << "fSignalOffset[0] = " << myFH->fSignalOffset[0] << "\n"; cout << "nSignalType = " << myFH->nSignalType << "\n"; cout << "nTelegraphEnable[0] = " << myFH->nTelegraphEnable[0] << "\n"; cout << "fTelegraphAdditGain[0] = " << myFH->fTelegraphAdditGain[0] << "\n"; cout << "lHeaderSize = " << myFH->lHeaderSize << "\n"; //Extract channel 0 signal assuming multiplexed two channel gap-free data //Extract parameters to convert ADC values to User Units float fADCToUUFactor; float fADCToUUShift; ABFH_GetADCtoUUFactors(myFH, 0, &fADCToUUFactor, &fADCToUUShift); cout << "pfADCToUUFactor = " << fADCToUUFactor << "\n"; cout << "pfADCToUUShift = " << fADCToUUShift << "\n"; //Print column headers cout.width(10); cout << "Sample"; cout.width(15); cout << "Amplitude" << endl; //Prepare to extract data buffer by buffer long maxSampleBuf = 8192; //Maximum buffer size long lread = 0; //Multiplexed Sample number long lremain = myFH->lActualAcqLength; //Number of unread samples short *ADCbuf = new short[8192]; //Buffer to hold two-byte ADC values float fUUValue; //ADC value converted to User Units long lbuf = (maxSampleBuf < lremain) ? maxSampleBuf : lremain; //Position random-access index at beginning of channel 0 data fin.seekg(myFH->lDataSectionPtr * 512, ios_base::beg); while (lbuf != 0) { //While there is a buffer full of unread points //Fetch two-bytes, lbuf times fin.read((char * ) ADCbuf, 2 * lbuf); //Process the buffer for (int i = 0 ; i < lbuf; i++) { if (lread % 2 == 0) { //But only if the two-channel multiplexed value belongs to channel 0 //Convert ADC values to User Units fUUValue = ADCbuf[i] * fADCToUUFactor + fADCToUUShift; //Print data cout.width(10); cout << lread; cout.width(15); cout << fUUValue << "\n"; } lread++; } lremain = myFH->lActualAcqLength - lread; lbuf = (maxSampleBuf < lremain) ? maxSampleBuf : lremain; } delete [] ADCbuf; delete myFH; //Close file fin.close(); return 0; }