Beispiel #1
0
bool glfHandler::NextSection()
{
    if (isStub)
    {
        endOfSection = true;
        data.recordType = 0;
        maxPosition = 1999999999;
        position = maxPosition + 1;
        return true;
    }

    while (!endOfSection && !ifeof(handle))
        NextEntry();

    endOfSection = false;

    int labelLength = 0;

    currentSection++;
    position = 0;
    if (ifread(handle, &labelLength, sizeof(int)) == sizeof(int))
    {
        ifread(handle, label.LockBuffer(labelLength+1), labelLength * sizeof(char));
        label.UnlockBuffer();

        maxPosition = 0;
        ifread(handle, &maxPosition, sizeof(int));

        return ((maxPosition > 0) && !ifeof(handle));
    }

    return false;
}
Beispiel #2
0
// Read the refSection from the specified file.  Assumes the file is in
// the correct position for reading the refSection.
bool GlfRefSection::read(IFILE filePtr)
{
    // Read the reference sequence name length
    int numRead = 0;
    int32_t refNameLen = 0;
    int byteLen = sizeof(int32_t);
    numRead = ifread(filePtr, &refNameLen, byteLen);
    if(numRead != byteLen)
    {
        // If no bytes were read and it is the end of the file, then return
        // false, but do not throw an exception.  This is not an error, just
        // the end of the file.
        if((numRead == 0) && ifeof(filePtr))
        {
            return(false);
        }

        String errorMsg =
            "Failed to read the length of the reference sequence name (";
        errorMsg += byteLen;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }

    // Read the refSection from the file.
    numRead = myRefName.readFromFile(filePtr, refNameLen);
    if(numRead != refNameLen)
    {
        String errorMsg = "Failed to read the reference sequence name (";
        errorMsg += refNameLen;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }

    // Read the ref length.
    byteLen = sizeof(uint32_t);
    numRead = ifread(filePtr, &myRefLen, byteLen);
    if(numRead != byteLen)
    {
        String errorMsg = "Failed to read the reference sequence length (";
        errorMsg += byteLen;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }

    // Successfully read, return success.
    return(true);
}
Beispiel #3
0
// Read the header from the specified file.  Assumes the file is in
// the correct position for reading the header.
bool GlfHeader::read(IFILE filePtr)
{
    if((filePtr == NULL) || (filePtr->isOpen() == false))
    {
        // File is not open, return failure.
        std::string errorString = 
            "Failed to read the header since the file is not open.";
        throw(GlfException(GlfStatus::FAIL_ORDER, errorString));
        return(false);
    }

    // Read the magic
    int numRead = 0;
    char magic[GLF_MAGIC_LEN];
    numRead = ifread(filePtr, &magic, GLF_MAGIC_LEN);
    if(numRead != GLF_MAGIC_LEN)
    {
        String errorMsg = "Failed to read the magic number (";
        errorMsg += GLF_MAGIC_LEN;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }
    // Read the header length.
    int32_t headerLen = 0;
    int byteLen = sizeof(int32_t);
    numRead = ifread(filePtr, &headerLen, byteLen);
    if(numRead != byteLen)
    {
        String errorMsg = "Failed to read the length of the header text (";
        errorMsg += byteLen;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }
       
    // Read the header from the file.
    numRead = myText.readFromFile(filePtr, headerLen);
    if(numRead != headerLen)
    {
        String errorMsg = "Failed to read the header text (";
        errorMsg += headerLen;
        errorMsg += " bytes).  Only read ";
        errorMsg += numRead;
        errorMsg += " bytes.";
        std::string errorString = errorMsg.c_str();
        throw(GlfException(GlfStatus::FAIL_IO, errorString));
        return(false);
    }
    // Successfully read, return success.
    return(true);
}
Beispiel #4
0
bool glfHandler::ReadHeader()
{
    if (isStub)
        return true;

    if (handle == NULL)
        return false;

    char magicNumber[4];

    if (ifread(handle, magicNumber, 4) != 4)
    {
        errorMsg = "unexpected end of file";
        return false;
    }

    if (magicNumber[0] != 'G' || magicNumber[1] != 'L' || magicNumber[2] != 'F')
    {
        errorMsg = "invalid format";
        return false;
    }

    if (magicNumber[3] != 3)
    {
        errorMsg = "unsupported version";
        return false;
    }

    unsigned int headerLength = 0;

    if (ifread(handle, &headerLength, 4) != 4)
    {
        errorMsg = "unexpected end of file";
        return false;
    }

    if (headerLength > 1024 * 1024)
    {
        errorMsg = "header too large -- bailing";
        return false;
    }

    header.SetLength(headerLength + 1);
    header[headerLength] = 0;

    if (headerLength && ifread(handle, header.LockBuffer(headerLength + 1), headerLength) != headerLength)
    {
        errorMsg = "unexpected end of file";
        return false;
    }

    return true;
}
Beispiel #5
0
void yFile::GetDataByFile()
{
	std::ifstream ifread(m_fileName);
	std::string szBuf;

	if (!ifread.is_open())
	{
		return;
	}


	while (getline(ifread,szBuf))
	{
		std::size_t pos = szBuf.find('=');
		if (std::string::npos == pos)
		{
			break;
		}
		else
		{
			m_data.insert(std::pair<std::string, std::string>(
				szBuf.substr(0, pos), szBuf.substr(pos + 1)));
		}
		szBuf.erase();
	}

	ifread.close();
}
Beispiel #6
0
// Read & parse the specified index file.
StatGenStatus::Status Tabix::readIndex(const char* filename)
{
    // Reset the index from anything that may previously be set.
    resetIndex();

    IFILE indexFile = ifopen(filename, "rb");

    // Failed to open the index file.
    if(indexFile == NULL)
    {
        return(StatGenStatus::FAIL_IO);
    }

    // read the tabix index structure.

    // Read the magic string.
    char magic[4];
    if(ifread(indexFile, magic, 4) != 4)
    {
        // Failed to read the magic
        return(StatGenStatus::FAIL_IO);
    }

    // If this is not an index file, set num references to 0. 
    if (magic[0] != 'T' || magic[1] != 'B' || magic[2] != 'I' || magic[3] != 1)
    {
        // Not a Tabix Index file.
        return(StatGenStatus::FAIL_PARSE);
    }

    // It is a tabix index file.
    // Read the number of reference sequences.
    if(ifread(indexFile, &n_ref, 4) != 4)
    {
        // Failed to read.
        return(StatGenStatus::FAIL_IO);
    }

    // Size the references.
    myRefs.resize(n_ref);

    // Read the Format configuration.
    if(ifread(indexFile, &myFormat, sizeof(myFormat)) != sizeof(myFormat))
    {
        // Failed to read.
        return(StatGenStatus::FAIL_IO);
    }

    // Read the length of the chromosome names.
    uint32_t l_nm;

    if(ifread(indexFile, &l_nm, sizeof(l_nm)) != sizeof(l_nm))
    {
        // Failed to read.
        return(StatGenStatus::FAIL_IO);
    }

    // Read the chromosome names.
    myChromNamesBuffer = new char[l_nm];
    if(ifread(indexFile, myChromNamesBuffer, l_nm) != l_nm)
    {
        return(StatGenStatus::FAIL_IO);
    }
    myChromNamesVector.resize(n_ref);

    // Parse out the chromosome names.
    bool prevNull = true;
    int chromIndex = 0;
    for(uint32_t i = 0; i < l_nm; i++)
    {
        if(chromIndex >= n_ref)
        {
            // already set the pointer for the last chromosome name, 
            // so stop looping.
            break;
        }
        if(prevNull == true)
        {
            myChromNamesVector[chromIndex++] = myChromNamesBuffer + i;
            prevNull = false;
        }
        if(myChromNamesBuffer[i] == '\0')
        {
            prevNull = true;
        }
    }

    for(int refIndex = 0; refIndex < n_ref; refIndex++)
    {
        // Read each reference.
        Reference* ref = &(myRefs[refIndex]);
        
        // Resize the bins so they can be indexed by bin number.
        ref->bins.resize(MAX_NUM_BINS + 1);
        
        // Read the number of bins.
        if(ifread(indexFile, &(ref->n_bin), 4) != 4)
        {
            // Failed to read the number of bins.
            // Return failure.
            return(StatGenStatus::FAIL_PARSE);
        }

        // Read each bin.
        for(int binIndex = 0; binIndex < ref->n_bin; binIndex++)
        {
            uint32_t binNumber;

            // Read in the bin number.
            if(ifread(indexFile, &(binNumber), 4) != 4)
            {
                // Failed to read the bin number.
                // Return failure.
                return(StatGenStatus::FAIL_IO);
            }

            // Add the bin to the reference and get the
            // pointer back so the values can be set in it.
            Bin* binPtr = &(ref->bins[binNumber]);
            binPtr->bin = binNumber;
         
            // Read in the number of chunks.
            if(ifread(indexFile, &(binPtr->n_chunk), 4) != 4)
            {
                // Failed to read number of chunks.
                // Return failure.
                return(StatGenStatus::FAIL_IO);
            }

            // Read in the chunks.
            // Allocate space for the chunks.
            uint32_t sizeOfChunkList = binPtr->n_chunk * sizeof(Chunk);
            binPtr->chunks = (Chunk*)malloc(sizeOfChunkList);
            if(ifread(indexFile, binPtr->chunks, sizeOfChunkList) != sizeOfChunkList)
            {
                // Failed to read the chunks.
                // Return failure.
                return(StatGenStatus::FAIL_IO);
            }
        }

        // Read the number of intervals.
        if(ifread(indexFile, &(ref->n_intv), 4) != 4)
        {
            // Failed to read, set to 0.
            ref->n_intv = 0;
            // Return failure.
            return(StatGenStatus::FAIL_IO);
        }

        // Allocate space for the intervals and read them.
        uint32_t linearIndexSize = ref->n_intv * sizeof(uint64_t);
        ref->ioffsets = (uint64_t*)malloc(linearIndexSize);
        if(ifread(indexFile, ref->ioffsets, linearIndexSize) != linearIndexSize)
        {
            // Failed to read the linear index.
            // Return failure.
            return(StatGenStatus::FAIL_IO);
        }
    }

    // Successfully read teh bam index file.
    return(StatGenStatus::SUCCESS);
}
Beispiel #7
0
EXTERN_C void sopen_abf_read(HDRTYPE* hdr) {	
/*
	this function will be called by the function SOPEN in "biosig.c"
	Input: 
		char* Header	// contains the file content
	Output: 
		HDRTYPE *hdr	// defines the HDR structure accoring to "biosig.h"
*/	

	if (VERBOSE_LEVEL>7) fprintf(stdout,"sopen_abf_read 101\n");

		size_t count = hdr->HeadLen; 	
		hdr->VERSION = lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fFileVersionNumber));

		hdr->HeadLen = (hdr->VERSION < 1.6) ? ABF_OLDHEADERSIZE : ABF_HEADERSIZE;
		if (count < hdr->HeadLen) {
			hdr->AS.Header = (uint8_t*) realloc(hdr->AS.Header, hdr->HeadLen);
			count         += ifread(hdr->AS.Header+count, 1, hdr->HeadLen-count, hdr);
		}
		hdr->HeadLen = count;
		assert(hdr->HeadLen == leu32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lHeaderSize)));

		{
			struct tm t;
			uint32_t u = leu32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lFileStartDate));
			t.tm_year = u / 10000 - 1900;
			t.tm_mon  = (u % 10000)/100 - 1;
			t.tm_mday = (u % 100);
			u = leu32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lFileStartTime));
			t.tm_hour = u / 3600;
			t.tm_min = (u % 3600)/60;
			t.tm_sec = (u % 60);
			//u = leu16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nFileStartMillisecs));
			hdr->T0 = tm_time2gdf_time(&t);
		}

		uint16_t gdftyp = 3;
		switch (lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDataFormat))) {
		case 0: gdftyp = 3; break;
		case 1: gdftyp = 16; break;
		}

		size_t slen;
		slen = min(MAX_LENGTH_MANUF, sizeof(((struct ABFFileHeader*)(hdr->AS.Header))->sCreatorInfo));
		slen = min(MAX_LENGTH_MANUF, ABF_CREATORINFOLEN);
		strncpy(hdr->ID.Manufacturer._field, (char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sCreatorInfo), slen);
		hdr->ID.Manufacturer._field[slen] = 0;
		hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field;
		slen = min(MAX_LENGTH_RID, sizeof(((struct ABFFileHeader*)(hdr->AS.Header))->sFileComment));
		strncpy(hdr->ID.Recording,(char*)hdr->AS.Header + offsetof(struct ABFFileHeader, sFileComment), slen);
		hdr->ID.Recording[slen] = 0;

		if (VERBOSE_LEVEL>7) {
			fprintf(stdout,"sCreatorInfo:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, sCreatorInfo));
			fprintf(stdout,"_sFileComment:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, _sFileComment));
			fprintf(stdout,"sFileComment:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, sFileComment));
			fprintf(stdout,"sFileComment:\t%s\n",hdr->AS.Header + offsetof(struct ABFFileHeader, sFileComment));


			fprintf(stdout,"\nlHeaderSize:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lHeaderSize)));
			fprintf(stdout,"lTagSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lTagSectionPtr)));
			fprintf(stdout,"lNumTagEntries:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumTagEntries)));
			fprintf(stdout,"lVoiceTagPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lVoiceTagPtr)));
			fprintf(stdout,"lVoiceTagEntries:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lVoiceTagEntries)));
			fprintf(stdout,"lSynchArrayPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lSynchArrayPtr)));
			fprintf(stdout,"lSynchArraySize:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lSynchArraySize)));

			fprintf(stdout,"\nlDataSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDataSectionPtr)));
			fprintf(stdout,"lScopeConfigPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lScopeConfigPtr)));
			fprintf(stdout,"lNumScopes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumScopes)));
			fprintf(stdout,"_lDACFilePtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, _lDACFilePtr)));
			fprintf(stdout,"_lDACFileNumEpisodes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, _lDACFileNumEpisodes)));
			fprintf(stdout,"lDeltaArrayPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDeltaArrayPtr)));
			fprintf(stdout,"lNumDeltas:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumDeltas)));
			fprintf(stdout,"nDataFormat:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDataFormat)));
			fprintf(stdout,"nSimultaneousScan:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nSimultaneousScan)));
			fprintf(stdout,"lStatisticsConfigPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lStatisticsConfigPtr)));
			fprintf(stdout,"lAnnotationSectionPtr:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lAnnotationSectionPtr)));
			fprintf(stdout,"lNumAnnotations:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumAnnotations)));

			fprintf(stdout,"\nlNumSamplesPerEpisode:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumSamplesPerEpisode)));
			fprintf(stdout,"lPreTriggerSamples:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lPreTriggerSamples)));
			fprintf(stdout,"lEpisodesPerRun:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lEpisodesPerRun)));
			fprintf(stdout,"lActualAcqLength:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualAcqLength)));
			fprintf(stdout,"lActualEpisodes:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lActualEpisodes)));
			fprintf(stdout,"lRunsPerTrial:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lRunsPerTrial)));
			fprintf(stdout,"lNumberOfTrials:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lNumberOfTrials)));
			fprintf(stdout,"fADCRange:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange)));
			fprintf(stdout,"fDACRange:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACRange)));
			fprintf(stdout,"lADCResolution:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lADCResolution)));
			fprintf(stdout,"lDACResolution:\t%i\n",lei32p(hdr->AS.Header + offsetof(struct ABFFileHeader, lDACResolution)));

			fprintf(stdout,"\nchannel_count_acquired:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, channel_count_acquired)));
			fprintf(stdout,"nADCNumChannels:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nADCNumChannels)));
			fprintf(stdout,"fADCSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval)));
			fprintf(stdout,"nDigitalDACChannel:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalDACChannel)));
			fprintf(stdout,"nOperationMode:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nOperationMode)));
			fprintf(stdout,"nDigitalEnable:\t%i\n",lei16p(hdr->AS.Header + offsetof(struct ABFFileHeader, nDigitalEnable)));

			fprintf(stdout,"\nfFileVersionNumber:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fFileVersionNumber)));
			fprintf(stdout,"fHeaderVersionNumber:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fHeaderVersionNumber)));
			fprintf(stdout,"fADCSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSampleInterval)));
			fprintf(stdout,"fADCSecondSampleInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCSecondSampleInterval)));
			fprintf(stdout,"fSynchTimeUnit:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSynchTimeUnit)));
			fprintf(stdout,"fSecondsPerRun:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fSecondsPerRun)));
			fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold)));

			fprintf(stdout,"\nfScopeOutputInterval:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fScopeOutputInterval)));
			fprintf(stdout,"fEpisodeStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fEpisodeStartToStart)));
			fprintf(stdout,"fRunStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fRunStartToStart)));
			fprintf(stdout,"fTrialStartToStart:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTrialStartToStart)));
			fprintf(stdout,"fStatisticsPeriod:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fStatisticsPeriod)));
			fprintf(stdout,"fADCRange:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fADCRange)));
			fprintf(stdout,"fDACRange:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold)));
			fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fDACRange)));
			fprintf(stdout,"dFileDuration:\t%g\n",lef64p(hdr->AS.Header + offsetof(struct ABFFileHeader, dFileDuration)));
			fprintf(stdout,"fTriggerThreshold:\t%f\n",lef32p(hdr->AS.Header + offsetof(struct ABFFileHeader, fTriggerThreshold)));

		}
Beispiel #8
0
// Open a sam/bam file for reading with the specified filename.
bool SamFile::OpenForRead(const char * filename, SamFileHeader* header)
{
    // Reset for any previously operated on files.
    resetFile();

    int lastchar = 0;

    while (filename[lastchar] != 0) lastchar++;

    // If at least one character, check for '-'.
    if((lastchar >= 1) && (filename[0] == '-'))
    {
        // Read from stdin - determine type of file to read.
        // Determine if compressed bam.
        if(strcmp(filename, "-.bam") == 0)
        {
            // Compressed bam - open as bgzf.
            // -.bam is the filename, read compressed bam from stdin
            filename = "-";

            myFilePtr = new InputFile;
            // support recover mode - this switches in a reader
            // capable of recovering from bad BGZF compression blocks.
            myFilePtr->setAttemptRecovery(myAttemptRecovery);
            myFilePtr->openFile(filename, "rb", InputFile::BGZF);

            myInterfacePtr = new BamInterface;

            // Read the magic string.
            char magic[4];
            ifread(myFilePtr, magic, 4);
        }
        else if(strcmp(filename, "-.ubam") == 0)
        {
            // uncompressed BAM File.
            // -.ubam is the filename, read uncompressed bam from stdin.
            // uncompressed BAM is still compressed with BGZF, but using
            // compression level 0, so still open as BGZF since it has a
            // BGZF header.
            filename = "-";

            // Uncompressed, so do not require the eof block.
#ifdef __ZLIB_AVAILABLE__
            BgzfFileType::setRequireEofBlock(false);
#endif
            myFilePtr = ifopen(filename, "rb", InputFile::BGZF);
        
            myInterfacePtr = new BamInterface;

            // Read the magic string.
            char magic[4];
            ifread(myFilePtr, magic, 4);
        }
        else if((strcmp(filename, "-") == 0) || (strcmp(filename, "-.sam") == 0))
        {
            // SAM File.
            // read sam from stdin
            filename = "-";
            myFilePtr = ifopen(filename, "rb", InputFile::UNCOMPRESSED);
            myInterfacePtr = new SamInterface;
        }
        else
        {
            std::string errorMessage = "Invalid SAM/BAM filename, ";
            errorMessage += filename;
            errorMessage += ".  From stdin, can only be '-', '-.sam', '-.bam', or '-.ubam'";
            myStatus.setStatus(SamStatus::FAIL_IO, errorMessage.c_str());
            delete myFilePtr;
            myFilePtr = NULL;
            return(false);          
        }
    }
    else
    {
        // Not from stdin.  Read the file to determine the type.

        myFilePtr = new InputFile;

        // support recovery mode - this conditionally enables a reader
        // capable of recovering from bad BGZF compression blocks.
        myFilePtr->setAttemptRecovery(myAttemptRecovery);
        bool rc = myFilePtr->openFile(filename, "rb", InputFile::DEFAULT);

        if (rc == false)
        {
            std::string errorMessage = "Failed to Open ";
            errorMessage += filename;
            errorMessage += " for reading";
            myStatus.setStatus(SamStatus::FAIL_IO, errorMessage.c_str());
            delete myFilePtr;
            myFilePtr = NULL;
            return(false);
        }
        
        char magic[4];
        ifread(myFilePtr, magic, 4);
        
        if (magic[0] == 'B' && magic[1] == 'A' && magic[2] == 'M' &&
            magic[3] == 1)
        {
            myInterfacePtr = new BamInterface;
            // Set that it is a bam file open for reading.  This is needed to
            // determine if an index file can be used.
            myIsBamOpenForRead = true;
        }
        else
        {
            // Not a bam, so rewind to the beginning of the file so it
            // can be read.
            ifrewind(myFilePtr);
            myInterfacePtr = new SamInterface;
        }
    }

    // File is open for reading.
    myIsOpenForRead = true;

    // Read the header if one was passed in.
    if(header != NULL)
    {
        return(ReadHeader(*header));
    }

    // Successfully opened the file.
    myStatus = SamStatus::SUCCESS;
    return(true);
}
Beispiel #9
0
bool glfHandler::NextEntry()
{
    if (isStub)
        return false;

    // Read record type
    if (endOfSection || (ifread(handle, &data, 1) != 1))
    {
        endOfSection = true;
        data.recordType = 0;
        position = maxPosition + 1;
        return false;
    }

    // printf("%d/%d\n", data.recordType, data.refBase);

    if (position > maxPosition)
        return true;

    switch (data.recordType)
    {
    case 0 :
        endOfSection = true;
        position = maxPosition + 1;
        return true;
    case 1 :
        if (ifread(handle,((char *) &data) + 1, sizeof(data) - 1) == sizeof(data) - 1)
        {
            data.refBase = translateBase[data.refBase];

            for (int i = 0; i < 10; i++)
                likelihoods[i] = bQualityConvertor.toDouble(data.lk[i]);

            position = position + data.offset;
            return true;
        }

        // Premature end of file
        data.recordType = 0;
        position = maxPosition + 1;
        return false;
    case 2 :
        while (ifread(handle, ((char *) &data) + 1, sizeof(data) - 4) == sizeof(data) - 4)
        {
            data.refBase = translateBase[data.refBase];

            for (int i = 0; i < 3; i++)
                likelihoods[i] = bQualityConvertor.toDouble(data.indel.lk[i]);

            position = position + data.offset;

            indelSequence[0].SetLength(abs(data.indel.length[0]) + 1);
            indelSequence[0][abs(data.indel.length[0])] = 0;
            if (ifread(handle, indelSequence[0].LockBuffer(), abs(data.indel.length[0])) != (unsigned int) abs(data.indel.length[0]))
                break;

            indelSequence[1].SetLength(abs(data.indel.length[1]) + 1);
            indelSequence[1][abs(data.indel.length[1])] = 0;
            if (ifread(handle, indelSequence[1].LockBuffer(), abs(data.indel.length[1])) != (unsigned int) abs(data.indel.length[1]))
                break;

            return true;
        }

        // Premature end of file
        data.recordType = 0;
        position = maxPosition + 1;
        return false;
    }

    return false;
}
Beispiel #10
0
EXTERN_C void sopen_alpha_read(HDRTYPE* hdr) {	
/*
	this function will be called by the function SOPEN in "biosig.c"

	Input: 
		char* Header	// contains the file content
		
	Output: 
		HDRTYPE *hdr	// defines the HDR structure accoring to "biosig.h"
*/	
    	size_t	 	count;
    	unsigned int 	k;
    	const char	*FileName = hdr->FileName; 

		fprintf(stdout,"Warning: support for alpha format is just experimental.\n"); 
		
		char* fn = (char*)malloc(strlen(hdr->FileName)+15);
		strcpy(fn,hdr->FileName); 	// Flawfinder: ignore
		
		const size_t bufsiz = 4096; 
		char buf[bufsiz]; 

		// alpha.alp  cal_res digin  digvidtc  eog  marker  measure  mkdef  montage  rawdata  rawhead  report.txt  r_info  sleep
		
		const char *f2 = "alpha.alp";		
		char *tmpstr   = strrchr(fn,FILESEP); 
		if (tmpstr) 	strcpy(tmpstr+1,f2);  	// Flawfinder: ignore
		else 	    	strcpy(fn,f2);  	// Flawfinder: ignore

		FILE *fid = fopen(fn,"r"); count  = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0;	// terminating 0 character 		
		char *t   = strtok(buf,"\xA\xD");
		while (t) {

if (VERBOSE_LEVEL>7) fprintf(stdout,"0: %s \n",t); 

			if (!strncmp(t,"Version = ",9))
				hdr->VERSION = atof(t+9);
			else if (!strncmp(t,"Id = ",4)) {
				strncpy(hdr->ID.Manufacturer._field,t+5,MAX_LENGTH_MANUF);
				hdr->ID.Manufacturer.Name = hdr->ID.Manufacturer._field;
			}
			t = strtok(NULL,"\xA\xD");
		}

		f2 = "rawhead";
		if (tmpstr) 	strcpy(tmpstr+1,f2); 	 	// Flawfinder: ignore
		else 	    	strcpy(fn,f2);  		// Flawfinder: ignore
				
		int Notch = 0; 		
		int Bits  = 0; 		
		double DigMax=0, DigMin=0; 
		uint16_t gdftyp = 0; 
		int ns = 0;
		fid = fopen(fn,"r"); count  = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0;	// terminating 0 character 		
		t   = strtok(buf,"\xA\xD");
		char STATUS = 1; 
		uint32_t *ChanOrder=NULL; 
		char **ChanType = NULL;
		while ((t!=NULL) && (STATUS<9)) {
			char *t1 = strchr(t,'=');

if (VERBOSE_LEVEL>7) fprintf(stdout,"<%6.2f> %i- %s | %s\n",hdr->VERSION, STATUS,t,t1); 
				
			if (t1) {
				t1[-1] = 0; t1++;
				
				if (STATUS == 1) {
					if (!strcmp(t,"Version")) 
						hdr->VERSION = atof(t1);
					else if (!strcmp(t,"BitsPerValue")) {
						Bits = atoi(t1);
						switch (Bits) {
						case 12: gdftyp = 255+12; 
						//	hdr->FILE.LittleEndian = 0;
						        DigMax =  (1<<(Bits-1))-1;
						        DigMin = -(1<<(Bits-1));
							break;
						case 16: gdftyp = 3; 
						        DigMax =  32752.0;  //!!! that's the maximum value found in alpha-trace files 
						        DigMin = -32736.0;  //!!! that's the minimum value found in alpha-trace files
						        break; 
						case 32: gdftyp = 5; break; 
						        DigMax =  (1<<(Bits-1))-1;
						        DigMin = -(1<<(Bits-1));
						}
					}	
					else if (!strcmp(t,"ChanCount")) {
						hdr->NS = atoi(t1);
						hdr->CHANNEL = (CHANNEL_TYPE*)realloc(hdr->CHANNEL, hdr->NS*sizeof(CHANNEL_TYPE));
						ChanOrder = (uint32_t*)calloc(hdr->NS,sizeof(uint32_t)*2);
						ChanType  = (char**)calloc(hdr->NS,sizeof(char*));
						
					}
					else if (!strcmp(t,"SampleFreq"))
						hdr->SampleRate = atof(t1);
					else if (!strcmp(t,"SampleCount")) {
						hdr->NRec = atoi(t1);
						hdr->SPR  = 1; 
					}
					else if (!strcmp(t,"NotchFreq")) 
						Notch = atof(t1);
					else if (!strcmp(t,"DispFlags") && (hdr->VERSION < 411.89)) 
						STATUS = 2;
					else if (!strcmp(t,"Sec2Marker") && (hdr->VERSION > 411.89)) 
						STATUS = 2;
				}		

				else if (STATUS == 2) {
					if (ns>=hdr->NS) {
						ns = 0; 
						STATUS = 3;
					}
					else {	
						CHANNEL_TYPE *hc = hdr->CHANNEL+ns; 
						hc->GDFTYP  = gdftyp; 
						hc->Notch   = Notch; 
						hc->LeadIdCode = 0; 
						hc->SPR = hdr->SPR; 
						//hc->bi8 = GDFTYP_BITS[gdftyp]*ns; 
						hc->DigMax  = DigMax;
						hc->DigMin  = DigMin;
						hc->OnOff   = 1; 
						hc->Cal     = 1.0; 
						hc->Off     = 0.0; 
						hc->PhysMax = hc->DigMax; 
						hc->PhysMin = hc->DigMin; 
					
						strncpy(hc->Label, t, MAX_LENGTH_LABEL+1);
						char* t2= strchr(t1,',');
						t2[0] = 0; while (isspace((++t2)[0]));
						char* t3= strchr(t2,',');
						t3[0] = 0; while (isspace((++t3)[0]));
						char* t4= strchr(t3,',');
						t4[0] = 0; while (isspace((++t4)[0]));

						ChanOrder[ns*2] = atoi(t2); 
						ChanOrder[ns*2+1] = ns; 
						ChanType[ns] = t3; 
						ns++;
					}	
				}	
				else if (STATUS == 3) {
					// decode information (filters, PhysDim, etc.) and assign to corresponding channels. 
					char *pd = NULL;
					float tmp1, tmp2, HighPass, LowPass;
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
					sscanf(t1, "%f, %f, %f, %f, %as", &HighPass,&LowPass, &tmp1,&tmp2, &pd); 
#else
					sscanf(t1, "%f, %f, %f, %f, %ms", &HighPass,&LowPass, &tmp1,&tmp2, &pd);
#endif
					strrchr(pd,',')[0]=0;
					if (!strcmp(pd,"%%")) pd[1]=0; 
					uint16_t pdc = PhysDimCode(pd); 
					if (pd) free(pd); 

					char flag = 0; 
					for (k=0; k < hdr->NS; k++) {
						if ((ChanType[k]!=NULL) && !strcmp(t,ChanType[k])) {
							CHANNEL_TYPE *hc = hdr->CHANNEL+k; 
							hc->PhysDimCode = pdc; 
							//strcpy(hc->PhysDim,pd); 
							hc->LowPass = LowPass;
							hc->HighPass = HighPass;
							ChanType[k] = NULL; 
						}
						if (ChanType[k] != NULL) flag = 1;	// not done yet 
					}	
					if (!flag) STATUS = 99; 	// done with channel definition
				}	
			}	
			t = strtok(NULL,"\xA\xD");
		}
		hdr->AS.bpb8 = (GDFTYP_BITS[gdftyp]*hdr->NS);
//		hdr->AS.bpb = (GDFTYP_BITS[gdftyp]*hdr->NS)>>3;		// do not rely on this, because some bits can get lost

		// sort channels 
		qsort(ChanOrder,hdr->NS,2*sizeof(uint32_t),&u32cmp);
		for (k=0; k<hdr->NS; k++) {
			hdr->CHANNEL[ChanOrder[2*k+1]].bi8 = GDFTYP_BITS[gdftyp]*k; 
			hdr->CHANNEL[ChanOrder[2*k+1]].bi  = (GDFTYP_BITS[gdftyp]*k)>>3; 
		}
		free(ChanOrder); 		
		free(ChanType); 		

		
		f2 = "cal_res";
		if (tmpstr) 	strcpy(tmpstr+1,f2); 	// Flawfinder: ignore
		else 	    	strcpy(fn,f2); 		// Flawfinder: ignore
				
		fid = fopen(fn,"r"); 
		if (fid!=NULL) {
			if (VERBOSE_LEVEL>7) fprintf(stdout,"cal_res: \n"); 

			count  = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0;	// terminating 0 character 		
			t   = strtok(buf,"\xA\xD");
			t   = strtok(NULL,"\xA\xD");	// skip lines 1 and 2 
			/*
			char label[MAX_LENGTH_LABEL+1];
			char flag[MAX_LENGTH_LABEL+1];
			double cal,off; 
			*/
			char *t0,*t1,*t2,*t3; 
			unsigned n=0; 	// 		
			for (k=0; max(k,n)<hdr->NS; k++) { 
				t = strtok(NULL,"\xA\xD");
			
				if (t==NULL) {	
					fprintf(stderr,"Warning SOPEN(alpha): scaling coefficients not defined for all channels\n");
					break;
				}

				// strncpy(hc->Label,t,min(strcspn(t," =,"),MAX_LENGTH_LABEL));
				t0 = strchr(t,'=');t0[0]=0;t0++;
				int ix = strlen(t)-1; 
				while ((ix>0) && isspace(t[ix])) t[ix--] = 0;	// remove trailing spaces
				t1 = strchr(t0,',');t1[0]=0;t1++;
				t2 = strchr(t1,',');t2[0]=0;t2++;
				t3 = strchr(t2,',');t3[0]=0;t3++;
	
				n  = atoi(t);	// n==0 if label is provided, n>0 if channel number is provided

/*				does not work because ambigous labels are used in rawhead and cal_res (e.g. T3 and T7)
				if (!n) for (n=0; n<hdr->NS; n++) {
					if (!strcmp(hdr->CHANNEL[n].Label,t))
					{ 	n++; 
						break; 
					}
				}
*/				

				if (VERBOSE_LEVEL>7) fprintf(stdout,"cal_res: %i %i <%s> %s %s %s\n",k,n,t,t1,t2,t3); 

				CHANNEL_TYPE *hc = hdr->CHANNEL + (n>0 ? n-1 : k); // channel can be denoted by label or number  	
				hc->Cal = atof(t1);
				hc->Off = 0; 
						
				if (VERBOSE_LEVEL>7) fprintf(stdout,"  <%s>   %s = ###, %f, %f\n", t1,hc->Label,hc->Cal,hc->Off);

				hc->PhysMax = (hc->DigMax - hc->Off) * hc->Cal;
				hc->PhysMin = (hc->DigMin - hc->Off) * hc->Cal;
				hc->XYZ[0]=0;
				hc->XYZ[1]=0;
				hc->XYZ[2]=0;
			}
		}
		
		f2 = "r_info";
		if (tmpstr) 	strcpy(tmpstr+1,f2);	// Flawfinder: ignore
		else 	    	strcpy(fn,f2);		// Flawfinder: ignore
				
		fid = fopen(fn,"r"); 
		if (fid!=NULL) {

			if (VERBOSE_LEVEL>7) fprintf(stdout,"r_info: \n"); 

			count  = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0;	// terminating 0 character 		
			struct tm T;
			t   = strtok(buf,"\xA\xD");
			t   = strtok(NULL,"\xA\xD");	// skip line 1 
			while (t!=NULL) {
				char *t1 = strchr(t,'=');
				t1[0] = 0;
				while (isspace((++t1)[0])); 
				for (k=strlen(t); (k>0) && isspace(t[--k]); t[k]=0);
				for (k=strlen(t1); (k>0) && isspace(t1[--k]); t1[k]=0);

			if (VERBOSE_LEVEL>7) fprintf(stdout,"r_info: %s = %s\n",t,t1); 

				if (0) {}
				else if (!strcmp(t,"RecId")) 
					strncpy(hdr->ID.Recording,t1,MAX_LENGTH_RID);
				else if (!strcmp(t,"RecDate")) {
					sscanf(t1,"%02d.%02d.%04d",&T.tm_mday,&T.tm_mon,&T.tm_year);
					T.tm_year -=1900;
					T.tm_mon -=1;
				}	
				else if (!strcmp(t,"RecTime"))
					sscanf(t1,"%02d.%02d.%02d",&T.tm_hour,&T.tm_min,&T.tm_sec);
				else if (!strcmp(t,"TechSal")) {
					if (hdr->ID.Technician) free(hdr->ID.Technician);
					hdr->ID.Technician = strdup(t1);
				}
				else if (!strcmp(t,"TechTitle") || !strcmp(t,"TechLast") || !strcmp(t,"TechFirst")) {
					size_t l0 = strlen(hdr->ID.Technician);
					size_t l1 = strlen(t1);
					hdr->ID.Technician = (char*)realloc(hdr->ID.Technician,l0+l1+2);
					hdr->ID.Technician[l0] = ' ';
					strcpy(hdr->ID.Technician+l0+1, t1);		// Flawfinder: ignore
				}	

				t = strtok(NULL,"\xA\xD");
			}
			hdr->T0 = tm_time2gdf_time(&T);
		}
		
		f2 = "marker";
		if (tmpstr) 	strcpy(tmpstr+1,f2); 		// Flawfinder: ignore
		else 	    	strcpy(fn,f2); 			// Flawfinder: ignore
		fid = fopen(fn,"r"); 
		if (fid != NULL) {
			size_t n,N;
			N=0; n=0;  
			while (!feof(fid)) {
				hdr->AS.auxBUF = (uint8_t*) realloc(hdr->AS.auxBUF,N+bufsiz+1);
				N += fread(hdr->AS.auxBUF+N, 1, bufsiz, fid); 
			}
			fclose(fid); 
			hdr->AS.auxBUF[N] = 0;	// terminating 0 character 		

			N = 0; 
			t = (char*)hdr->AS.auxBUF+strcspn((char*)hdr->AS.auxBUF,"\xA\xD");
			t = t+strspn(t,"\xA\xD");	// skip lines 1 and 2 
			while (t[0]) {
				char*  t1 = t;	
				size_t l1 = strcspn(t1,"="); 
				size_t p2 = strspn(t1+l1,"= ")+l1; 
				char*  t2 = t+p2;
				size_t l2 = strcspn(t2," ,"); 
				size_t p3 = strspn(t2+l2," ,")+l2; 
				char*  t3 = t2+p3;
				size_t l3 = strcspn(t3," ,"); 
				size_t p4 = strspn(t3+l3," ,")+l3; 
				char*  t4 = t3+p4;
				size_t l4 = strcspn(t4,"\xA\xD"); 
				size_t p5 = strspn(t4+l4,"\xA\xD")+l4;
				t1[l1] = 0;
				while (isspace(t1[--l1])) t1[l1]=0;
				t2[l2] = 0;
				t3[l3] = 0;
				t4[l4] = 0;
				t = t4 + p5;
				
				if (n+1 >= N) {
					const size_t sz = 100;
					hdr->EVENT.TYP = (typeof(hdr->EVENT.TYP)) realloc(hdr->EVENT.TYP,(N+sz)*sizeof(*hdr->EVENT.TYP));
					hdr->EVENT.POS = (typeof(hdr->EVENT.POS)) realloc(hdr->EVENT.POS,(N+sz)*sizeof(*hdr->EVENT.POS));
					N += sz; 
				}	

				hdr->EVENT.POS[n] = atol(t3);
				if (!strcmp(t1,"REC")) 
					hdr->EVENT.TYP[n] = 0x7ffe;
				else if (!strcmp(t1,"MON"))
					hdr->EVENT.TYP[n] = 0;
				else if (!strcmp(t1,"TXT"))
					FreeTextEvent(hdr, n, t4); 
				else
					FreeTextEvent(hdr, n, t1); 
						
				if (!strcmp(t2,"off")) 
					hdr->EVENT.TYP[n] |= 0x8000;	

//fprintf(stdout,"#%u, 0x%04x,%u | t1=<%s> = t2=<%s>, t3=<%s>, t4=<%s>\n",n,hdr->EVENT.TYP[n],hdr->EVENT.POS[n],t1,t2,t3,t4);

				n++;
//				t = strtok(NULL,"\xA\xD");

//fprintf(stdout," <%s>\n",t1);
			}	
			hdr->EVENT.N = n; 
			hdr->EVENT.SampleRate = hdr->SampleRate; 
//			convert2to4_eventtable(hdr);
		}

		tmpstr    = strrchr(fn,FILESEP); 
		tmpstr[0] = 0;	
		tmpstr    = strrchr(fn,FILESEP); 
		f2 = "s_info";
		if (tmpstr) 	strcpy(tmpstr+1,f2); 		// Flawfinder: ignore
		else 	    	strcpy(fn,f2); 			// Flawfinder: ignore
				
		fid = fopen(fn,"r"); 
		if (fid!=NULL) {
			count  = fread(buf,1,bufsiz-1,fid); fclose(fid); buf[count]=0;	// terminating 0 character 
			char *Lastname = NULL;		
			char *Firstname = NULL;		
			struct tm T;
			t   = strtok(buf,"\xA\xD");
			t   = strtok(NULL,"\xA\xD");	// skip line 1 
			while (t!=NULL) {
				char *t1 = strchr(t,'=');
				t1[0] = 0;
				while (isspace((++t1)[0])); 
				for (k=strlen(t); (k>0) && isspace(t[--k]); t[k]=0);
				for (k=strlen(t1); (k>0) && isspace(t1[--k]); t1[k]=0);

			if (VERBOSE_LEVEL>7) fprintf(stdout,"s_info: <%s> = <%s>\n",t,t1); 

				if (0) {}
				else if (!strcmp(t,"SubjId")) 
					strncpy(hdr->Patient.Id,t1,MAX_LENGTH_PID); 
				else if (!strcmp(t,"Gender")) 
					switch (t1[0]) {
					case 'm':
					case 'M':
						hdr->Patient.Sex = 1; break; 	
					case 'w':
					case 'W':
					case 'f':
					case 'F':
						hdr->Patient.Sex = 2; break; 	
					default: 	
						hdr->Patient.Sex = 0; break; 	
					}	
				else if (!strcmp(t,"Handedness")) 
					switch (t1[0]) {
					case 'r':
					case 'R':
						hdr->Patient.Handedness = 1; break; 	
					case 'l':
					case 'L':
						hdr->Patient.Handedness = 2; break; 	
					default: 	
						hdr->Patient.Handedness = 0; break; 	
					}	
				else if (!strcmp(t,"Size")) 
					hdr->Patient.Height = atof(t1); 
				else if (!strcmp(t,"Weight")) 
					hdr->Patient.Weight = atof(t1); 
				else if (!strcmp(t,"FirstName")) {
					Firstname = t1;
				}	
				else if (!strcmp(t,"LastName")) {
					Lastname = t1;
				}
				else if (!strcmp(t,"BirthDay")) {
					int c = sscanf(t1,"%02d.%02d.%04d",&T.tm_mday,&T.tm_mon,&T.tm_year);
					T.tm_year -=1900;
					T.tm_mon -=1;
					T.tm_hour =12;
					T.tm_min =0;
					T.tm_sec =0;
					if (c > 2) hdr->Patient.Birthday = tm_time2gdf_time(&T);
				}	
				t = strtok(NULL,"\xA\xD");
			}	

			size_t l0 = strlen(Firstname);
			size_t l1 = strlen(Lastname);
			if (l0+l1+1 <= MAX_LENGTH_NAME) {
				strcpy(hdr->Patient.Name, Firstname);			// Flawfinder: ignore
				hdr->Patient.Name[l0] = ' ';
				strcpy(hdr->Patient.Name + l0 + 1, Lastname);		// Flawfinder: ignore
			} else 
				strncpy(hdr->Patient.Name, Lastname, MAX_LENGTH_NAME+1); 	// Flawfinder: ignore
			
		}

		strcpy(fn,hdr->FileName); 		// Flawfinder: ignore
		tmpstr   = strrchr(fn,FILESEP);
		f2 = "rawdata";
		if (tmpstr) 	strcpy(tmpstr+1,f2);	// Flawfinder: ignore
		else 	    	strcpy(fn,f2);		// Flawfinder: ignore
				
		if (VERBOSE_LEVEL>7) fprintf(stdout,"rawdata11: %s \n",f2); 

		hdr->FileName = fn; 
		ifopen(hdr,"r"); 

		if (VERBOSE_LEVEL>7) fprintf(stdout,"rawdata22: %s open=%i\n",f2,hdr->FILE.OPEN); 
		if (hdr->FILE.OPEN) {
			int16_t a[3];
			ifread(a, 2, 3, hdr); 
			hdr->VERSION = a[0]; 
			hdr->HeadLen = 6; 
			
			switch (a[2]) {
			case 12: gdftyp = 255+12; break;
			case 16: gdftyp = 3; break; 
			case 32: gdftyp = 5; break; 
			}
			for (k=a[1]; k<hdr->NS; k++) 
				hdr->CHANNEL[k].OnOff = 0;  
			for (k=0; k<hdr->NS; k++) {
				hdr->CHANNEL[k].GDFTYP = gdftyp; 
			}

			hdr->AS.bpb = (GDFTYP_BITS[gdftyp]*a[1])>>3; 
			hdr->FILE.POS = 0;
			
			size_t len = (GDFTYP_BITS[gdftyp]*a[1]*hdr->NRec*hdr->SPR)>>3;	
			if ((GDFTYP_BITS[gdftyp]*a[1]) & 0x07) {
				/* hack: if SPR*NS*bits are not a multiple of bytes, 
				   hdr->AS.bpb would be non-integer causing some problems in SREAD reading the correct number of bytes. 
				   This hack makes sure that all data is loaded.  	
				*/
				len++;
			}	
			hdr->AS.rawdata = (uint8_t*) realloc(hdr->AS.rawdata, len);
			size_t count    = ifread(hdr->AS.rawdata,1,len,hdr);
			hdr->AS.first   = 0; 
			hdr->AS.length  = (count<<3)/(GDFTYP_BITS[gdftyp]*a[1]);
		}
Beispiel #11
0
// Read & parse the specified index file.
SamStatus::Status BamIndex::readIndex(const char* filename)
{
    // Reset the index from anything that may previously be set.
    resetIndex();

    IFILE indexFile = ifopen(filename, "rb");

    // Failed to open the index file.
    if(indexFile == NULL)
    {
        return(SamStatus::FAIL_IO);
    }

    // generate the bam index structure.

    // Read the magic string.
    char magic[4];
    if(ifread(indexFile, magic, 4) != 4)
    {
        // Failed to read the magic
        ifclose(indexFile);
        return(SamStatus::FAIL_IO);
    }

    // If this is not an index file, set num references to 0. 
    if (magic[0] != 'B' || magic[1] != 'A' || magic[2] != 'I' || magic[3] != 1)
    {
        // Not a BAM Index file.
        ifclose(indexFile);
        return(SamStatus::FAIL_PARSE);
    }

    // It is a bam index file.
    // Read the number of reference sequences.
    if(ifread(indexFile, &n_ref, 4) != 4)
    {
        // Failed to read.
        ifclose(indexFile);
        return(SamStatus::FAIL_IO);
    }

    // Size the references.
    myRefs.resize(n_ref);

    for(int refIndex = 0; refIndex < n_ref; refIndex++)
    {
        // Read each reference.
        Reference* ref = &(myRefs[refIndex]);
        
        // Read the number of bins.
        if(ifread(indexFile, &(ref->n_bin), 4) != 4)
        {
            // Failed to read the number of bins.
            // Return failure.
            ifclose(indexFile);
            return(SamStatus::FAIL_PARSE);
        }

        // If there are no bins, then there are no
        // mapped/unmapped reads.
        if(ref->n_bin == 0)
        {
            ref->n_mapped = 0;
            ref->n_unmapped = 0;
        }

        // Resize the bins so they can be indexed by bin number.
        ref->bins.resize(ref->n_bin + 1);
        
        // Read each bin.
        for(int binIndex = 0; binIndex < ref->n_bin; binIndex++)
        {
            uint32_t binNumber;

            // Read in the bin number.
            if(ifread(indexFile, &(binNumber), 4) != 4)
            {
                // Failed to read the bin number.
                // Return failure.
                ifclose(indexFile);
                return(SamStatus::FAIL_IO);
            }

            // Add the bin to the reference and get the
            // pointer back so the values can be set in it.
            Bin* binPtr = &(ref->bins[binIndex]);
            binPtr->bin = binNumber;
         
            // Read in the number of chunks.
            if(ifread(indexFile, &(binPtr->n_chunk), 4) != 4)
            {
                // Failed to read number of chunks.
                // Return failure.
                ifclose(indexFile);
                return(SamStatus::FAIL_IO);
            }

            // Read in the chunks.
            // Allocate space for the chunks.
            uint32_t sizeOfChunkList = binPtr->n_chunk * sizeof(Chunk);
            binPtr->chunks = (Chunk*)malloc(sizeOfChunkList);
            if(ifread(indexFile, binPtr->chunks, sizeOfChunkList) != sizeOfChunkList)
            {
                // Failed to read the chunks.
                // Return failure.
                ifclose(indexFile);
                return(SamStatus::FAIL_IO);
            }

            // Determine the min/max for this bin if it is not the max bin.
            if(binPtr->bin != MAX_NUM_BINS)
            {
                for(int i = 0; i < binPtr->n_chunk; i++)
                {
                    if(binPtr->chunks[i].chunk_beg < ref->minChunkOffset)
                    {
                        ref->minChunkOffset = binPtr->chunks[i].chunk_beg;
                    }
                    if(binPtr->chunks[i].chunk_end > ref->maxChunkOffset)
                    {
                        ref->maxChunkOffset = binPtr->chunks[i].chunk_end;
                    }
                    if(binPtr->chunks[i].chunk_end > maxOverallOffset)
                    {
                        maxOverallOffset = binPtr->chunks[i].chunk_end;
                    }
                }
            }
            else
            {
                // Mapped/unmapped are the last chunk of the
                // MAX BIN
                ref->n_mapped = binPtr->chunks[binPtr->n_chunk - 1].chunk_beg;
                ref->n_unmapped = binPtr->chunks[binPtr->n_chunk - 1].chunk_end;
            }
        }

        // Read the number of intervals.
        if(ifread(indexFile, &(ref->n_intv), 4) != 4)
        {
            // Failed to read, set to 0.
            ref->n_intv = 0;
            // Return failure.
            ifclose(indexFile);
            return(SamStatus::FAIL_IO);
        }

        // Allocate space for the intervals and read them.
        uint32_t linearIndexSize = ref->n_intv * sizeof(uint64_t);
        ref->ioffsets = (uint64_t*)malloc(linearIndexSize);
        if(ifread(indexFile, ref->ioffsets, linearIndexSize) != linearIndexSize)
        {
            // Failed to read the linear index.
            // Return failure.
            ifclose(indexFile);
            return(SamStatus::FAIL_IO);
        }
    }

    int32_t numUnmapped = 0;
    if(ifread(indexFile, &numUnmapped, sizeof(int32_t)) == sizeof(int32_t))
    {
        myUnMappedNumReads = numUnmapped;
    }

    // Successfully read the bam index file.
    ifclose(indexFile);
    return(SamStatus::SUCCESS);
}
Beispiel #12
0
void BedFile::openForRead(const char* bedFile, const char* bimFile, const char* famFile, const char* refFile, int nbuf) {
  StringArray tokens;

  reset();

  iFile = ifopen(bedFile,"rb");
  if ( iFile == NULL ) {
    throw VcfFileException("Failed opening file %s - %s",bedFile,strerror(errno));
  }
  
  // read magic numbers
  char magicNumbers[3] = {0x6c,0x1b,0x01};
  char firstThreeBytes[3];
  ifread( iFile, firstThreeBytes, 3 );
  for(int i=0; i < 3; ++i) {
    if ( firstThreeBytes[i] != magicNumbers[i] ) {
      throw VcfFileException("The magic numbers do not match in BED file %s",bedFile);
    }
  }

  iBimFile = ifopen(bimFile,"rb");
  iFamFile = ifopen(famFile,"rb");
  sRefFile = refFile;

  while( 1 ) {
    int ret = line.ReadLine(iFamFile);
    if ( ret <= 0 ) break;
    tokens.ReplaceTokens(line, " \t\r\n");
    if ( tokens.Length() < 5 ) {
      throw VcfFileException("Less then 5 columns are observed in FAM file");
    }
    VcfInd* p = new VcfInd(tokens[1],tokens[0],tokens[2],tokens[3],tokens[4]);
    vpVcfInds.push_back(p);
  }

  //Logger::gLogger->writeLog("Finished loading %d individuals from FAM file",(int)vpVcfInds.size());

  nBytes = (vpVcfInds.size()+3)/4;
  if ( pBedBuffer != NULL ) { delete[] pBedBuffer; }
  pBedBuffer = new char[nBytes];

  nBuffers = nbuf;
  nNumMarkers = 0;
  nHead = 0;

  bParseGenotypes = true;
  bParseDosages = false;
  bParseValues = false;

  if ( nBuffers == 0 ) { // infinite buffer size
    // do not set size of markers
  }
  else {
    vpVcfMarkers.resize( nBuffers );
    for(int i=0; i < nBuffers; ++i) {
      VcfMarker* p = new VcfMarker;
      vpVcfMarkers[i] = p;
    }
  }

  genomeSequence.setReferenceName(sRefFile.c_str());
  genomeSequence.useMemoryMap(true);

  //Logger::gLogger->writeLog("Loading reference file %s",sRefFile.c_str());

  if ( genomeSequence.open() ) {
    // write a message that new index file is being created
    if ( genomeSequence.create(false) ) {
      throw VcfFileException("Failed creating index file of the reference. Please check the file permission");
    }
    if ( genomeSequence.open() ) {
      throw VcfFileException("Failed opening index file of the reference.");
    }
  }
}
Beispiel #13
0
// Read a BAM file's header.
bool BamInterface::readHeader(IFILE filePtr, SamFileHeader& header,
                              SamStatus& status)
{
    if(filePtr == NULL)
    {
        // File is not open, return false.
        status.setStatus(SamStatus::FAIL_ORDER,
                         "Cannot read header since the file pointer is null");
        return(false);
    }
    if(filePtr->isOpen() == false)
    {
        status.setStatus(SamStatus::FAIL_ORDER,
                         "Cannot read header since the file is not open");
        return(false);
    }

    // Clear the passed in header.
    header.resetHeader();

    int32_t headerLength;
    int readSize = ifread(filePtr, &headerLength, sizeof(headerLength));

    if(readSize != sizeof(headerLength))
    {
        String errMsg = "Failed to read the BAM header length, read ";
        errMsg += readSize;
        errMsg += " bytes instead of ";
        errMsg += (unsigned int)sizeof(headerLength);
        status.setStatus(SamStatus::FAIL_IO, errMsg.c_str());
        return(false);
    }

    String headerStr;
    if(headerLength > 0)
    {
        // Read the header.
        readSize =
            ifread(filePtr, headerStr.LockBuffer(headerLength + 1), headerLength);
        headerStr[headerLength] = 0;
        headerStr.UnlockBuffer();
        if(readSize != headerLength)
        {
            // Failed to read the header.
            status.setStatus(SamStatus::FAIL_IO, "Failed to read the BAM header.");
            return(false);
        }
    }

    // Parse the header that was read.
    if(!header.addHeader(headerStr))
    {
        // Status is set in the method on failure.
        status.setStatus(SamStatus::FAIL_PARSE, header.getErrorMessage());
        return(false);
    }

    int referenceCount;
    // Read the number of references sequences.
    ifread(filePtr, &referenceCount, sizeof(int));

    // Get and clear the reference info so it can be set
    // from the bam reference table.
    SamReferenceInfo& refInfo =
        header.getReferenceInfoForBamInterface();
    refInfo.clear();

    CharBuffer refName;

    // Read each reference sequence
    for (int i = 0; i < referenceCount; i++)
    {
        int nameLength;
        int rc;
        // Read the length of the reference name.
        rc = ifread(filePtr, &nameLength, sizeof(int));
        if(rc != sizeof(int))
        {
            status.setStatus(SamStatus::FAIL_IO,
                             "Failed to read the BAM reference dictionary.");
            return(false);
        }

        // Read the name.
        refName.readFromFile(filePtr, nameLength);

        // Read the length of the reference sequence.
        int32_t refLen;
        rc = ifread(filePtr, &refLen, sizeof(int));

        if(rc != sizeof(int)) {
            status.setStatus(SamStatus::FAIL_IO,
                             "Failed to read the BAM reference dictionary.");
            return(false);
        }

        refInfo.add(refName.c_str(), refLen);
    }

    // Successfully read the file.
    return(true);
}
Beispiel #14
0
bool BedFile::iterateMarker() {
  // read a marker information from BIM file
  if ( line.ReadLine(iBimFile) > 0 ) {
    ++nNumLines;
  }
  else {
    return false;
  }
  lineTokens.ReplaceTokens(line, " \t\r\n");

  VcfMarker* pMarker;

  if ( nBuffers == 0 ) {
    pMarker = new VcfMarker;
    vpVcfMarkers.push_back(pMarker);
    ++nNumMarkers;
    ++nHead;
  }
  else {
    // make a circular list with constant size nBuffer
    pMarker = vpVcfMarkers[nHead];
    nHead = (nHead+1) % nBuffers;
    ++nNumMarkers;
  }

  if ( lineTokens.Length() < 6 ) {
    throw VcfFileException("BIM file has only %d columns - %s",lineTokens.Length(),lineTokens[0].c_str());
  }
  
  try {

    String strChr = lineTokens[0];
    if ( strChr.Compare("23") == 0 ) {
      strChr = "X";
    }
    else if ( strChr.Compare("24") == 0 ) {
      strChr = "Y";
    }
    else if ( strChr.Compare("25") == 0 ) {
      strChr = "XY";
    }
    else if ( strChr.Compare("26") == 0 ) {
      strChr = "MT";
    }

    // try to resolve different conventions for chromosome names by using
    // (1) original chr
    // (2) strChr : 23 -> "X", 24 -> "Y", 25 -> "XY", 26 -> "MT"
    // (3) "chr"+ chr
    // (4) "chr"+ strChr
    
    pMarker->setPos(lineTokens[3]);

    genomeIndex_t markerIndex = genomeSequence.getGenomePosition( lineTokens[0].c_str(), pMarker->nPos );
    if ( markerIndex == INVALID_GENOME_INDEX ) {
      // routines specific to BED file format
      markerIndex = genomeSequence.getGenomePosition( strChr.c_str(), pMarker->nPos );

      if ( markerIndex == INVALID_GENOME_INDEX ) {
	strChr = String("chr") + strChr;
	markerIndex = genomeSequence.getGenomePosition( strChr.c_str(), pMarker->nPos );
	if ( markerIndex == INVALID_GENOME_INDEX ) {
	  throw VcfFileException("Cannot parse chromosome name "+lineTokens[0]+" in BIM file");
	}
      }
    }

    pMarker->setChrom(strChr);
    pMarker->setID(lineTokens[1]);

    // determine refBase/altBase
    // if refBase matches a1 or a2, use it
    // if none matches and either is zero
    // do not allow for triallelic sites
    char refBase = genomeSequence[markerIndex];
    char a1 = lineTokens[4][0];
    char a2 = lineTokens[5][0];
    char altBase = determineAltBase(refBase, a1,a2);

    pMarker->setRef(String(refBase));
    pMarker->setAlts(String(altBase));

    // read genotypes
    ifread(iFile, pBedBuffer, nBytes);

    pMarker->setSampleSize((int)vpVcfInds.size(),bParseGenotypes,bParseDosages,bParseValues);
    int AC = 0, AN = 0, NS = 0;

    for(int i=0; i < (int)vpVcfInds.size(); ++i) {
      char g = (pBedBuffer[i/4] >> ((i % 4)*2)) & 0x03;

      //Logger::gLogger->writeLog("i = %d, g = %d",i,(int)g);
      switch(g) {
      case 0: // 0/0 -> 0x00
	if ( bRefIsAllele1 ) {
	  pMarker->setGenotype(i,0x0000); // 0/0
	}
	else {
	  pMarker->setGenotype(i,0x0101); // 0/0
	  AC += 2;
	}
	AN += 2;
	++NS;
	break;
      case 1:
	pMarker->setGenotype(i,0xffff); // missing
	break;
      case 2: // 0/1
	pMarker->setGenotype(i,0x0001); // 0/1
	++AC;
	AN += 2;
	++NS;
	break;
      case 3:
	if ( bRefIsAllele1 ) {
	  pMarker->setGenotype(i,0x0101); // 1/1
	  AC += 2;
	}
	else {
	  pMarker->setGenotype(i,0x0000); // 0/0
	}
	AN += 2;
	++NS;
	break;
      default:
	throw VcfFileException("Error in parsing genotypes");
      }
    }

    pMarker->setQual(".");
    pMarker->setFilters(".");

    String info;
    if ( AN > 0 ) {
      info.printf("NS=%d;AC=%d;AN=%d;AF=%.6lf",NS,AC,AN,(double)AC/(double)AN);
    }
    else {
      info.printf("NS=%d;AC=%d;AN=%d",NS,AC,AN);
    }
    pMarker->setInfo(info, false);

    return true;
  }
  catch (VcfFileException exc) {
    // add the line number to the error message
    throw VcfFileException(exc.msg + " See line " + nNumLines + ".");
  }
}
Beispiel #15
0
/****************************************************************************
   sopen_heka
     reads heka format 

     if itx is not null, the file is converted into an ITX formated file 
     and streamed to itx, too. 	
 ****************************************************************************/
void sopen_heka(HDRTYPE* hdr, FILE *itx) {
	size_t count = hdr->HeadLen;

	if (hdr->TYPE==HEKA && hdr->VERSION > 1) {

		int32_t Levels=0;
		uint16_t k;
		//int32_t *Sizes=NULL;
		int32_t Counts[5], counts[5]; //, Sizes[5];
		memset(Counts,0,20);
		memset(counts,0,20);
		//memset(Sizes,0,20);
		uint32_t StartOfData=0,StartOfPulse=0;

		union {
			struct {
				int32_t Root;
				int32_t Group;
				int32_t Series;
				int32_t Sweep;
				int32_t Trace;
			} Rec;
			int32_t all[5];
		} Sizes;


    		// HEKA PatchMaster file format

		count = hdr->HeadLen;
		struct stat FileBuf;
		stat(hdr->FileName,&FileBuf);
		hdr->AS.Header = (uint8_t*)realloc(hdr->AS.Header, FileBuf.st_size);
		count += ifread(hdr->AS.Header+count, 1, 1024-count, hdr);
		hdr->HeadLen = count;

		hdr->FILE.LittleEndian = *(uint8_t*)(hdr->AS.Header+52) > 0;
		char SWAP = ( hdr->FILE.LittleEndian && (__BYTE_ORDER == __BIG_ENDIAN))  \
			 || (!hdr->FILE.LittleEndian && (__BYTE_ORDER == __LITTLE_ENDIAN));

		if (SWAP) {
			biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format requires data swapping - this is not supported yet.");
			return;
		}
		SWAP = 0;  // might be useful for compile time optimization

		/* get file size and read whole file */
		count += ifread(hdr->AS.Header+count, 1, FileBuf.st_size - count, hdr);

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %i bytes read\n",__FILE__,__LINE__,__func__, count);

		// double oTime;
		uint32_t nItems;
		if (hdr->FILE.LittleEndian) {
			// oTime  = lef64p(hdr->AS.Header+40);	// not used
			nItems = leu32p(hdr->AS.Header+48);
		}
		else {
			// oTime  = bef64p(hdr->AS.Header+40);	// not used
			nItems = beu32p(hdr->AS.Header+48);
		}

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): nItems=%i\n",__FILE__,__LINE__,__func__, nItems);

		if (hdr->VERSION == 1) {
			Sizes.Rec.Root   = 544;
			Sizes.Rec.Group  = 128;
			Sizes.Rec.Series = 1120;
			Sizes.Rec.Sweep  = 160;
			Sizes.Rec.Trace  = 296;
		}
		else if (hdr->VERSION == 2)
		for (k=0; k < min(12,nItems); k++) {

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA nItems=%i\n",__func__,__LINE__, k);

			uint32_t start  = *(uint32_t*)(hdr->AS.Header+k*16+64);
			uint32_t length = *(uint32_t*)(hdr->AS.Header+k*16+64+4);
			if (SWAP) {
				start  = bswap_32(start);
				length = bswap_32(length);
			}
			uint8_t *ext = hdr->AS.Header + k*16 + 64 + 8;

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA #%i: <%s> [%i:+%i]\n",__func__,__LINE__,k,ext,start,length);

			if (!start) break;

			if ((start+8) > count) {
				biosigERROR(hdr,  B4C_INCOMPLETE_FILE, "Heka/Patchmaster: file is corrupted - segment with pulse data is not available!");
				return;
			}

			if (!memcmp(ext,".pul\0\0\0\0",8)) {
				// find pulse data
				ifseek(hdr, start, SEEK_SET);

				//magic  = *(int32_t*)(hdr->AS.Header+start);
				Levels = *(int32_t*)(hdr->AS.Header+start+4);
				if (SWAP) Levels = bswap_32(Levels);
				if (Levels>5) {
					biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster format with more than 5 levels not supported");
					return;
				}

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i): HEKA #%i    Levels=%i\n",__func__,__LINE__,k,Levels);

				memcpy(Sizes.all,hdr->AS.Header+start+8,sizeof(int32_t)*Levels);
				if (SWAP) {
					int l;
					for (l=0; l < Levels; l++) Sizes.all[l] = bswap_32(Sizes.all[l]);
				}

if (VERBOSE_LEVEL>7) {int l; for (l=0; l < Levels; l++) fprintf(stdout,"%s (line %i): HEKA #%i       %i\n",__func__,__LINE__,l, Sizes.all[l]); }

				StartOfPulse = start + 8 + 4 * Levels;
			}

			else if (!memcmp(ext,".dat\0\0\0\0",8)) {
				StartOfData = start;
			}
		}

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): \n",__FILE__,__LINE__,__func__);

		// if (!Sizes) free(Sizes); Sizes=NULL;

/* DONE: HEKA, check channel number and label 
	pass 1:
		+ get number of sweeps
		+ get number of channels
		+ check whether all traces of a single sweep have the same SPR, and Fs
		+ check whether channelnumber (TrAdcChannel), scaling (DataScaler) and Label fit among all sweeps
		+ extract the total number of samples
		+ physical units
		+ level 4 may have no children
		+ count event descriptions Level2/SeLabel
	pass 2:
		+ initialize data to NAN
		+ skip sweeps if selected channel is not in it
		+ Y scale, physical scale
		+ Event.CodeDescription, Events,
		resampling
*/

		uint32_t k1=0, k2=0, k3=0, k4=0;
		uint32_t K1=0, K2=0, K3=0, K4=0, K5=0;
		double t;
		size_t pos;

		// read K1
		if (SWAP) {
			K1 		= bswap_32(*(uint32_t*)(hdr->AS.Header + StartOfPulse + Sizes.Rec.Root));
			hdr->VERSION 	= bswap_32(*(uint32_t*)(hdr->AS.Header + StartOfPulse));
			union {
				double f64;
				uint64_t u64;
			} c;	
			c.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header + StartOfPulse + 520));
			t = c.f64;
		} else {
			K1 		= (*(uint32_t*)(hdr->AS.Header + StartOfPulse + Sizes.Rec.Root));
			hdr->VERSION 	= (*(uint32_t*)(hdr->AS.Header + StartOfPulse));
			t  		= (*(double*)(hdr->AS.Header + StartOfPulse + 520));
		}

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): \n",__FILE__,__LINE__,__func__);
		
		hdr->T0 = heka2gdftime(t);	// this is when when heka was started, data is recorded later.
		hdr->SampleRate = 0.0;
		double *DT = NULL; 	// list of sampling intervals per channel
		hdr->SPR = 0;

if (VERBOSE_LEVEL>7) fprintf(stdout,"%s (line %i) %s(...): %p\n",__FILE__,__LINE__,__func__,hdr->EVENT.CodeDesc);

		/*******************************************************************************************************
			HEKA: read structural information
 		 *******************************************************************************************************/

		pos = StartOfPulse + Sizes.Rec.Root + 4;
		size_t EventN=0;

		for (k1=0; k1<K1; k1++)	{
		// read group

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L1 @%i=\t%i/%i \n",(int)(pos+StartOfData),k1,K1);

			pos += Sizes.Rec.Group+4;
			// read number of children
			K2 = (*(uint32_t*)(hdr->AS.Header+pos-4));

			hdr->AS.auxBUF = (uint8_t*)realloc(hdr->AS.auxBUF,K2*33);	// used to store name of series
			for (k2=0; k2<K2; k2++)	{
				// read series
				union {
					double   f64;
					uint64_t u64;
				} Delay;
				char *SeLabel =  (char*)(hdr->AS.Header+pos+4);		// max 32 bytes
				strncpy((char*)hdr->AS.auxBUF + 33*k2, (char*)hdr->AS.Header+pos+4, 32); hdr->AS.auxBUF[33*k2+32] = 0;
				SeLabel = (char*)hdr->AS.auxBUF + 33*k2;
				double tt  = *(double*)(hdr->AS.Header+pos+136);		// time of series. TODO: this time should be taken into account 
				Delay.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header+pos+472+176));

				gdf_time t = heka2gdftime(tt);
		
				struct tm tm;
				gdf_time2tm_time_r(t,&tm); 
if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L2 @%i=%s %f\t%i/%i %i/%i     t=%.17g %s\n",(int)(pos+StartOfData),SeLabel,Delay.f64,k1,K1,k2,K2,ldexp(t,-32),asctime(&tm));

				pos += Sizes.Rec.Series + 4;
				// read number of children
				K3 = (*(uint32_t*)(hdr->AS.Header+pos-4));
				if (EventN <= hdr->EVENT.N + K3 + 2) {
					EventN = max(max(16,EventN),hdr->EVENT.N+K3+2) * 2;
					if (reallocEventTable(hdr, EventN) == SIZE_MAX) {
						biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "Allocating memory for event table failed.");
						return;
					};
				}

				if (!hdr->AS.SegSel[0] && !hdr->AS.SegSel[1] && !hdr->AS.SegSel[2]) {
					// in case of reading the whole file (no sweep selection), include marker for start of series
					FreeTextEvent(hdr, hdr->EVENT.N, SeLabel);
					hdr->EVENT.POS[hdr->EVENT.N] = hdr->SPR;	// within reading the structure, hdr->SPR is used as a intermediate variable counting the number of samples
#if (BIOSIG_VERSION >= 10500)
					hdr->EVENT.TimeStamp[hdr->EVENT.N] = t;
#endif
					hdr->EVENT.N++;
				}

				for (k3=0; k3<K3; k3++)	{
					// read sweep
					hdr->NRec++; 	// increase number of sweeps
					size_t SPR = 0, spr = 0;
					gdf_time t   = heka2gdftime(*(double*)(hdr->AS.Header+pos+48));		// time of sweep. TODO: this should be taken into account 

					gdf_time2tm_time_r(t,&tm); 

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L3 @%i= %fHz\t%i/%i %i/%i %i/%i %s\n",(int)(pos+StartOfData),hdr->SampleRate,k1,K1,k2,K2,k3,K3,asctime(&tm));

					char flagSweepSelected = (hdr->AS.SegSel[0]==0 || k1+1==hdr->AS.SegSel[0])
						              && (hdr->AS.SegSel[1]==0 || k2+1==hdr->AS.SegSel[1])
							      && (hdr->AS.SegSel[2]==0 || k3+1==hdr->AS.SegSel[2]);

					// hdr->SPR
					if (hdr->SPR==0)
						hdr->T0 = t; 		// start time of first recording determines the start time of the recording
					else if (flagSweepSelected && hdr->SPR > 0) {
						// marker for start of sweep
						hdr->EVENT.POS[hdr->EVENT.N] = hdr->SPR;	// within reading the structure, hdr->SPR is used as a intermediate variable counting the number of samples
						hdr->EVENT.TYP[hdr->EVENT.N] = 0x7ffe;
#if (BIOSIG_VERSION >= 10500)
						hdr->EVENT.TimeStamp[hdr->EVENT.N] = t;
#endif
						hdr->EVENT.N++;
					}

					pos += Sizes.Rec.Sweep + 4;
					// read number of children
					K4 = (*(uint32_t*)(hdr->AS.Header+pos-4));
					for (k4=0; k4<K4; k4++)	{
						// read trace
						double DigMin, DigMax;
						uint16_t gdftyp  = 0;
						uint32_t ns      = (*(uint32_t*)(hdr->AS.Header+pos+36));
						uint32_t DataPos = (*(uint32_t*)(hdr->AS.Header+pos+40));
						spr              = (*(uint32_t*)(hdr->AS.Header+pos+44));
						double DataScaler= (*(double*)(hdr->AS.Header+pos+72));
						double Toffset   = (*(double*)(hdr->AS.Header+pos+80));		// time offset of 
						uint16_t pdc     = PhysDimCode((char*)(hdr->AS.Header + pos + 96));
						double dT        = (*(double*)(hdr->AS.Header+pos+104));
						//double XStart    = (*(double*)(hdr->AS.Header+pos+112));
						uint16_t XUnits  = PhysDimCode((char*)(hdr->AS.Header+pos+120));
						double YRange    = (*(double*)(hdr->AS.Header+pos+128));
						double YOffset   = (*(double*)(hdr->AS.Header+pos+136));
						double Bandwidth = (*(double*)(hdr->AS.Header+pos+144));
						//double PipetteResistance  = (*(double*)(hdr->AS.Header+pos+152));
						double RsValue   = (*(double*)(hdr->AS.Header+pos+192));

						uint8_t ValidYRange = hdr->AS.Header[pos+220];
						uint16_t AdcChan = (*(uint16_t*)(hdr->AS.Header+pos+222));
						/* obsolete: range is defined by DigMin/DigMax * DataScaler + YOffset
						double PhysMin   = (*(double*)(hdr->AS.Header+pos+224));
						double PhysMax   = (*(double*)(hdr->AS.Header+pos+232));
						*/

if (VERBOSE_LEVEL>7) fprintf(stdout, "%s (line %i): %i %i %i %i %i %g %g 0x%x xUnits=%i %g %g %g %g %i %i\n", __FILE__,__LINE__, k1, k2, k3, k4, ns, DataScaler, Toffset, pdc, XUnits, YRange, YOffset, Bandwidth, RsValue, ValidYRange, AdcChan);

						switch (hdr->AS.Header[pos+70]) {
						case 0: gdftyp = 3; 		//int16
							/*
								It seems that the range is 1.024*(2^15-1)/2^15 nA or V
								and symetric around zero. i.e. YOffset is zero
							*/
							DigMax =  ldexp(1.0,15) - 1.0;
							DigMin = -DigMax;
							break;
						case 1: gdftyp = 5; 		//int32
							DigMax =  ldexp(1.0, 31) - 1.0;
							DigMin = -DigMax;
							break;
						case 2: gdftyp = 16; 		//float32
							DigMax =  1e9;
							DigMin = -1e9;
							break;
						case 3: gdftyp = 17; 		//float64
							DigMax =  1e9;
							DigMin = -1e9;
							break;
						default:
							DigMax =  NAN;
							DigMin =  NAN;
							biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: data type not supported");
						};

						if (SWAP) {
 							AdcChan = bswap_16(AdcChan);
 							ns  = bswap_32(ns);
 							DataPos = bswap_32(DataPos);
							spr = bswap_32(spr);
							// avoid breaking strict-aliasing rules
							union {
								double f64;
								uint64_t u64;
							} c;	
							c.f64 = dT;      c.u64 = bswap_64(c.u64); dT      = c.f64;
							c.f64 = YRange;  c.u64 = bswap_64(c.u64); YRange  = c.f64;
							c.f64 = YOffset; c.u64 = bswap_64(c.u64); YOffset = c.f64;
							//c.f64 = PhysMax; c.u64 = bswap_64(c.u64); PhysMax = c.f64;
							//c.f64 = PhysMin; c.u64 = bswap_64(c.u64); PhysMin = c.f64;
							c.f64 = Toffset; c.u64 = bswap_64(c.u64); Toffset = c.f64;
 						}

						if (YOffset != 0.0) 
							fprintf(stderr,"!!! WARNING !!!  HEKA: the offset is not zero - "
							"this case is not tested and might result in incorrect scaling of "
							"the data,\n!!! YOU ARE WARNED !!!\n"); 

						// scale to standard units - no prefix 	
						double Cal = DataScaler * PhysDimScale(pdc);
						double Off = YOffset * PhysDimScale(pdc);
						pdc &= 0xffe0; 
						float Fs = 1.0 / ( dT  * PhysDimScale(XUnits) ) ;  // float is used to avoid spurios accuracy, round to single precision accuracy

						if (flagSweepSelected) {

							if (hdr->SampleRate <= 0.0) hdr->SampleRate = Fs;
                                                        if (fabs(hdr->SampleRate - Fs) > 1e-9*Fs) {
								long DIV1 = 1, DIV2 = 1;
								rational(hdr->SampleRate*dT*PhysDimScale(XUnits), 1e-6, &DIV2, &DIV1);

								if (DIV1 > 1) {
									if ( ((size_t)DIV1 * hdr->SPR) > 0xffffffffffffffff) {
										fprintf(stderr,"!!! WARNING sopen_heka(%s) !!! due to resampling, the data will have more then 2^31 samples !!!\n", hdr->FileName);
										biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"HEKA file has more than 2^32 samples - this is not supported yet");
									}
									hdr->SPR *= DIV1;
									hdr->SampleRate *= DIV1;
							                hdr->EVENT.SampleRate = hdr->SampleRate;
									size_t n = 0;
									while (n < hdr->EVENT.N)
										hdr->EVENT.POS[n++] *= DIV1;
								}	
								if (DIV2 > 1) spr *= DIV2;
							}

							// samples per sweep
							if (k4==0) SPR = spr;
							else if (SPR != spr) {
								biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: number of samples among channels within a single sweep do not match.");
								return;
							}
						}

						char *Label = (char*)hdr->AS.Header+pos+4;
						for (ns=0; ns < hdr->NS; ns++) {
							if (!strcmp(hdr->CHANNEL[ns].Label,Label)) break;
						}

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L4 @%i= #%i,%i, %s %f %fHz\t%i/%i %i/%i %i/%i %i/%i \n",(int)(pos+StartOfData),ns,AdcChan,Label,hdr->SampleRate,Fs,k1,K1,k2,K2,k3,K3,k4,K4);
		
						CHANNEL_TYPE *hc;
						if (ns >= hdr->NS) {
							hdr->NS = ns + 1;
#ifdef WITH_TIMESTAMPCHANNEL
							// allocate memory for an extra time stamp channel, which is define only after the end of the channel loop - see below
							hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, (hdr->NS + 1) * sizeof(CHANNEL_TYPE));  
#else
							hdr->CHANNEL = (CHANNEL_TYPE*) realloc(hdr->CHANNEL, hdr->NS * sizeof(CHANNEL_TYPE));  
#endif
							hc = hdr->CHANNEL + ns;
							strncpy(hc->Label, Label, max(32, MAX_LENGTH_LABEL));
							hc->Label[max(32,MAX_LENGTH_LABEL)] = 0;
							hc->Transducer[0] = 0;
                                                        hc->SPR     = 1;
							hc->PhysDimCode = pdc;
                                                        hc->OnOff   = 1;
							hc->GDFTYP  = gdftyp;
							hc->LeadIdCode = 0;
							hc->DigMin  = DigMin;
							hc->DigMax  = DigMax;

							// TODO: case of non-zero YOffset is not tested //
							hc->PhysMax = DigMax * Cal + Off;
							hc->PhysMin = DigMin * Cal + Off;

							hc->Cal = Cal;
							hc->Off = Off;
							hc->TOffset = Toffset;

#ifndef NDEBUG
							double Cal2 = (hc->PhysMax - hc->PhysMin) / (hc->DigMax - hc->DigMin);
							double Off2 = hc->PhysMin - Cal2 * hc->DigMin;
							double Off3 = hc->PhysMax - Cal2 * hc->DigMax;

if (VERBOSE_LEVEL>6) fprintf(stdout,"HEKA L5 @%i= #%i,%i, %s %g/%g %g/%g \n",(int)(pos+StartOfData),ns,AdcChan,Label,Cal,Cal2,Off,Off2);

							assert(Cal==Cal2);
							assert(Off==Off2);
							assert(Off==Off3);
#endif

							/* TODO: fix remaining channel header  */
							/* LowPass, HighPass, Notch, Impedance, */
							hc->HighPass = NAN;
							hc->LowPass = (Bandwidth > 0) ? Bandwidth : NAN;
							hc->Notch = NAN;
							hc->Impedance = (RsValue > 0) ? RsValue : NAN;	

							DT = (double*) realloc(DT, hdr->NS*sizeof(double));
							DT[ns] = dT;
						}
						else {
							/*
							   channel has been already defined in earlier sweep.
							   check compatibility and adapt internal format when needed
							*/
							hc = hdr->CHANNEL + ns;
							double PhysMax = DigMax * Cal + Off;
							double PhysMin = DigMin * Cal + Off;
							// get max value to avoid false positive saturation detection when scaling changes
							if (hc->PhysMax < PhysMax) hc->PhysMax = PhysMax;
							if (hc->PhysMin > PhysMin) hc->PhysMin = PhysMin;

							if (hc->GDFTYP < gdftyp) {
								/* when data type changes, use the largest data type */
								if (4 < hc->GDFTYP && hc->GDFTYP < 9 && gdftyp==16)
									/* (U)INT32, (U)INT64 + FLOAT32 -> DOUBLE */
									hc->GDFTYP = 17; 	
								else 
									hc->GDFTYP = gdftyp; 
							}
							else if (hc->GDFTYP > gdftyp) {
								/* when data type changes, use the largest data type */
								if (4 < gdftyp && gdftyp < 9 && hc->GDFTYP==16)
									/* (U)INT32, (U)INT64 + FLOAT32 -> DOUBLE */
									hc->GDFTYP = 17; 	
							}

							if (fabs(hc->Cal - Cal) > 1e-9*Cal) {
								/* when scaling changes from sweep to sweep, use floating point numbers internally. */
								if (hc->GDFTYP < 5) // int16 or smaller 
									hc->GDFTYP = 16;
								else if (hc->GDFTYP < 9) // int32, int64 -> double
									hc->GDFTYP = 17;
							} 

							if ((pdc & 0xFFE0) != (hc->PhysDimCode & 0xFFE0)) {
	                                                        fprintf(stdout, "ERROR: [%i,%i,%i,%i] Yunits in %s do not match %04x(%s) ! %04x(%s)\n",k1,k2,k3,k4, Label, pdc, PhysDim3(pdc), hc->PhysDimCode, PhysDim3(hc->PhysDimCode));
								biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: Yunits do not match");
							}
	                                                if ( ( VERBOSE_LEVEL > 7 ) && ( fabs( DT[ns] - dT) > 1e-9 * dT) ) {
								fprintf(stdout, "%s (line %i) different sampling rates [%i,%i,%i,%i]#%i,%f/%f \n",__FILE__,__LINE__,(int)k1,(int)k2,(int)k3,(int)k4,(int)ns, 1.0/DT[ns],1.0/dT);
	                                                }
						}

						if (YOffset) {
							biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: YOffset is not zero");
						}
						if (hdr->AS.Header[pos+220] != 1) {
							fprintf(stderr,"WARNING Heka/Patchmaster: ValidYRange not set to 1 but %i in sweep [%i,%i,%i,%i]\n", hdr->AS.Header[pos+220],k1+1,k2+1,k3+1,k4+1);
						}

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA L6 @%i= #%i,%i, %s %f-%fHz\t%i/%i %i/%i %i/%i %i/%i \n",(int)(pos+StartOfData),ns,AdcChan,Label,hdr->SampleRate,Fs,k1,K1,k2,K2,k3,K3,k4,K4);

						pos += Sizes.Rec.Trace+4;
						// read number of children -- this should be 0 - ALWAYS;
						K5 = (*(uint32_t*)(hdr->AS.Header+pos-4));
						if (K5) {
							biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster: Level 4 has some children");
						}
					}	// end loop k4

					// if sweep is selected, add number of samples to counter 
					if (flagSweepSelected) {
						if ( hdr->SPR > 0xffffffffffffffffu-SPR) {
							biosigERROR(hdr,B4C_FORMAT_UNSUPPORTED,"HEKA file has more than 2^32 samples - this is not supported yet");
						}
						hdr->SPR += SPR;
					}
				}		// end loop k3
			}			// end loop k2
		}				// end loop k1

#ifndef NO_BI
		if (DT) free(DT);
#else
		size_t *BI = (size_t*) DT;      // DT is not used anymore, use space for BI
#endif
                DT = NULL;

#ifdef WITH_TIMESTAMPCHANNEL
		{
			/*
				define time stamp channel, memory is already allocated above
			*/		
			CHANNEL_TYPE *hc = hdr->CHANNEL + hdr->NS; 
			hc->GDFTYP  = 7; 	// corresponds to int64_t, gdf_time
			strcpy(hc->Label,"Timestamp");
			hc->Transducer[0]=0;
			hc->PhysDimCode = 2272; // units: days [d]
                        hc->LeadIdCode = 0;
                        hc->SPR     = 1;
			hc->Cal     = ldexp(1.0, -32); 
			hc->Off     = 0.0; 
			hc->OnOff   = 1; 
			hc->DigMax  = ldexp( 1.0, 61); 	
			hc->DigMin  = 0; 	
			hc->PhysMax = hc->DigMax * hc->Cal;  	
			hc->PhysMin = hc->DigMin * hc->Cal;
			hc->TOffset   = 0.0; 
			hc->Impedance = NAN; 
			hc->HighPass = NAN; 
			hc->LowPass  = NAN; 
			hc->Notch    = NAN; 
			hc->XYZ[0] = 0.0; 
			hc->XYZ[1] = 0.0; 
			hc->XYZ[2] = 0.0; 

			hdr->NS++;
		}
#endif

		hdr->NRec = 1;
		hdr->AS.bpb = 0;
		for (k = 0; k < hdr->NS; k++) {
			CHANNEL_TYPE *hc = hdr->CHANNEL + k;

			hc->Cal = (hc->PhysMax - hc->PhysMin) / (hc->DigMax - hc->DigMin); 
			hc->Off = hc->PhysMin - hc->DigMin * hc->Cal;
#ifndef NO_BI
			hc->bi = hdr->AS.bpb;
#else
			BI[k] = hdr->AS.bpb;
#endif
			hc->SPR = hdr->SPR;
			hdr->AS.bpb += hc->SPR * (GDFTYP_BITS[hc->GDFTYP]>>3);	// multiplation must not exceed 32 bit limit
		}

		if (hdr->AS.B4C_ERRNUM) {
#ifdef NO_BI
			if (BI) free(BI);
#endif
 			return;
		}
		hdr->ID.Manufacturer.Name = "HEKA/Patchmaster"; 



/******************************************************************************
      SREAD_HEKA 

      void sread_heka(HDRTYPE* hdr, FILE *itx, ... ) {

 ******************************************************************************/

if (VERBOSE_LEVEL > 7) fprintf(stdout,"HEKA: 400: %"PRIi64"  %"PRIi32" %"PRIi64"\n",hdr->NRec, hdr->AS.bpb, hdr->NRec * (size_t)hdr->AS.bpb);

		size_t sz = hdr->NRec * (size_t)hdr->AS.bpb;
		if (sz/hdr->NRec < hdr->AS.bpb) {
                        biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed - more than 2GB required but platform supports only 32 bit!");
                        return;
		}

		void* tmpptr = realloc(hdr->AS.rawdata, sz);
		if (tmpptr!=NULL) 
			hdr->AS.rawdata = (uint8_t*) tmpptr;
		else {
                        biosigERROR(hdr, B4C_MEMORY_ALLOCATION_FAILED, "memory allocation failed - not enough memory!");
                        return;
		}	
		assert(hdr->NRec >= 0);
		memset(hdr->AS.rawdata, 0xff, hdr->NRec * (size_t)hdr->AS.bpb); 	// initialize with NAN's


#ifdef NO_BI
#define _BI (BI[k])
#else
#define _BI (hc->bi)
#endif
		/* initialize with NAN's */
		for (k=0; k<hdr->NS; k++) {
			size_t k1;
			CHANNEL_TYPE *hc = hdr->CHANNEL+k;
			switch (hc->GDFTYP) {
			case 3:
				for (k1=0; k1<hc->SPR; k1++) {
                                        *(uint16_t*)(hdr->AS.rawdata + _BI + k1 * 2) = 0x8000;
                                }
				break;
			case 5:
				for (k1=0; k1<hc->SPR; k1++) *(uint32_t*)(hdr->AS.rawdata + _BI + k1 * 4) = 0x80000000;
				break;
			case 7:
				for (k1=0; k1<hc->SPR; k1++) *(int64_t*)(hdr->AS.rawdata + _BI + k1 * 4) = 0x8000000000000000LL;
				break;
			case 16:
				for (k1=0; k1<hc->SPR; k1++) *(float*)(hdr->AS.rawdata + _BI + k1 * 4) = NAN;
				break;
			case 17:
				for (k1=0; k1<hc->SPR; k1++) *(double*)(hdr->AS.rawdata + _BI + k1 * 8) = NAN;
				break;
			}
		}
#undef _BI

		char *WAVENAME = NULL; 
		if (itx) {
			fprintf(itx, "IGOR\r\nX Silent 1\r\n");
			const char *fn = strrchr(hdr->FileName,'\\');
			if (fn) fn++;
			else fn = strrchr(hdr->FileName,'/');
			if (fn) fn++;
			else fn = hdr->FileName;

			size_t len = strspn(fn,"."); 
			WAVENAME = (char*)malloc(strlen(hdr->FileName)+7);
			if (len) 
				strncpy(WAVENAME, fn, len); 
			else 
				strcpy(WAVENAME, fn); 		// Flawfinder: ignore
		}

if (VERBOSE_LEVEL>7) hdr2ascii(hdr,stdout,4);

		/*******************************************************************************************************
			HEKA: read data blocks
 		 *******************************************************************************************************/
		uint32_t SPR = 0;
		pos = StartOfPulse + Sizes.Rec.Root + 4;
		for (k1=0; k1<K1; k1++)	{
		// read group

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L1 @%i=\t%i/%i \n",(int)(pos+StartOfData),k1,K1);

			pos += Sizes.Rec.Group+4;
			// read number of children
			K2 = (*(uint32_t*)(hdr->AS.Header+pos-4));

			for (k2=0; k2<K2; k2++)	{
				// read series
				union {
					double   f64;
					uint64_t u64;
				} Delay;
				uint32_t spr = 0;
				char *SeLabel = (char*)(hdr->AS.Header+pos+4);		// max 32 bytes
				Delay.u64 = bswap_64(*(uint64_t*)(hdr->AS.Header+pos+472+176));

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L2 @%i=%s %f\t%i/%i %i/%i \n",(int)(pos+StartOfData),SeLabel,Delay.f64,k1,K1,k2,K2);

				/* move to reading of data */
				pos += Sizes.Rec.Series+4;
				// read number of children
				K3 = (*(uint32_t*)(hdr->AS.Header+pos-4));
				for (k3=0; k3<K3; k3++)	{
#if defined(WITH_TIMESTAMPCHANNEL)

#ifdef NO_BI
#define _BI (BI[hdr->NS-1])
#else
#define _BI (hdr->CHANNEL[hdr->NS-1].bi)
#endif
					gdf_time t = heka2gdftime(*(double*)(hdr->AS.Header+pos+48));		// time of sweep. TODO: this should be taken into account 
					*(int64_t*)(hdr->AS.rawdata + _BI + SPR * 8) = t;
#undef _BI

#endif // WITH_TIMESTAMPCHANNEL
					// read sweep
					char flagSweepSelected = (hdr->AS.SegSel[0]==0 || k1+1==hdr->AS.SegSel[0])
						              && (hdr->AS.SegSel[1]==0 || k2+1==hdr->AS.SegSel[1])
							      && (hdr->AS.SegSel[2]==0 || k3+1==hdr->AS.SegSel[2]);

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L3 @%i=\t%i/%i %i/%i %i/%i sel=%i\n",(int)(pos+StartOfData),k1,K1,k2,K2,k3,K3,flagSweepSelected);

					pos += Sizes.Rec.Sweep + 4;
					// read number of children
					K4 = (*(uint32_t*)(hdr->AS.Header+pos-4));
					size_t DIV=1;
					for (k4=0; k4<K4; k4++)	{
						if (!flagSweepSelected) {
							pos += Sizes.Rec.Trace+4;
							continue;
						}

						// read trace
						uint16_t gdftyp  = 0;	
						uint32_t ns      = (*(uint32_t*)(hdr->AS.Header+pos+36));
						uint32_t DataPos = (*(uint32_t*)(hdr->AS.Header+pos+40));
						spr              = (*(uint32_t*)(hdr->AS.Header+pos+44));
						double DataScaler= (*(double*)(hdr->AS.Header+pos+72));
						double Toffset   = (*(double*)(hdr->AS.Header+pos+80));		// time offset of 
						uint16_t pdc     = PhysDimCode((char*)(hdr->AS.Header + pos + 96));
						char *physdim    = (char*)(hdr->AS.Header + pos + 96);
						double dT        = (*(double*)(hdr->AS.Header+pos+104));
//						double XStart    = (*(double*)(hdr->AS.Header+pos+112));
//						uint16_t XUnits  = PhysDimCode((char*)(hdr->AS.Header+pos+120));
						double YRange    = (*(double*)(hdr->AS.Header+pos+128));
						double YOffset   = (*(double*)(hdr->AS.Header+pos+136));
//						double Bandwidth = (*(double*)(hdr->AS.Header+pos+144));
						uint16_t AdcChan = (*(uint16_t*)(hdr->AS.Header+pos+222));
/*
						double PhysMin   = (*(double*)(hdr->AS.Header+pos+224));
						double PhysMax   = (*(double*)(hdr->AS.Header+pos+232));
*/
						switch (hdr->AS.Header[pos+70]) {
						case 0: gdftyp = 3;  break;	// int16
						case 1: gdftyp = 5;  break;	// int32
						case 2: gdftyp = 16; break;	// float32
						case 3: gdftyp = 17; break;	// float64
						default: 
							biosigERROR(hdr, B4C_FORMAT_UNSUPPORTED, "Heka/Patchmaster unknown data type is used");
						};

						if (SWAP) {
 							AdcChan  = bswap_16(AdcChan);
 							ns       = bswap_32(ns);
 							DataPos  = bswap_32(DataPos);
							spr      = bswap_32(spr);
							// avoid breaking strict-aliasing rules
							union {
								double f64;
								uint64_t u64;
							} c;	
							c.f64 = dT;      c.u64 = bswap_64(c.u64); dT      = c.f64;
							c.f64 = YRange;  c.u64 = bswap_64(c.u64); YRange  = c.f64;
							c.f64 = YOffset; c.u64 = bswap_64(c.u64); YOffset = c.f64;
/*
							c.f64 = PhysMax; c.u64 = bswap_64(c.u64); PhysMax = c.f64;
							c.f64 = PhysMin; c.u64 = bswap_64(c.u64); PhysMin = c.f64;
*/
							c.f64 = Toffset; c.u64 = bswap_64(c.u64); Toffset = c.f64;
 						}
                                                double Fs  = round(1.0 / dT);
						DIV = round(hdr->SampleRate / Fs);

						char *Label = (char*)(hdr->AS.Header+pos+4);
						for (ns=0; ns < hdr->NS; ns++) {
							if (!strcmp(hdr->CHANNEL[ns].Label, Label)) break;
						}
						CHANNEL_TYPE *hc = hdr->CHANNEL+ns;

if (VERBOSE_LEVEL>7) fprintf(stdout,"HEKA+L4 @%i= #%i,%i,%i/%i %s\t%i/%i %i/%i %i/%i %i/%i DIV=%i,%i,%i\n",(int)(pos+StartOfData),ns,AdcChan,spr,SPR,Label,k1,K1,k2,K2,k3,K3,k4,K4,(int)DIV,gdftyp,hc->GDFTYP);

						if (itx) {
							uint32_t k5;
							double Cal = DataScaler;

							assert(hdr->CHANNEL[ns].Off==0.0);
							double Off = 0.0; 

							fprintf(itx, "\r\nWAVES %s_%i_%i_%i_%i\r\nBEGIN\r\n", WAVENAME,k1+1,k2+1,k3+1,k4+1);
							switch (hc->GDFTYP) {
							case 3:  
								for (k5 = 0; k5 < spr; ++k5)
									fprintf(itx,"% e\n", (double)*(int16_t*)(hdr->AS.Header + DataPos + k5 * 2) * Cal + Off);
								break;
							case 5:
								for (k5 = 0; k5 < spr; ++k5)
									fprintf(itx,"% e\n", (double)*(int32_t*)(hdr->AS.Header + DataPos + k5 * 4) * Cal + Off);
								break;
							case 16: 
								for (k5 = 0; k5 < spr; ++k5)
									fprintf(itx,"% e\n", (double)*(float*)(hdr->AS.Header + DataPos + k5 * 4) * Cal + Off);
								break;
							case 17: 
								for (k5 = 0; k5 < spr; ++k5)
									fprintf(itx,"% e\n", *(double*)(hdr->AS.Header + DataPos + k5 * 8) * Cal + Off);
								break;
							}
							fprintf(itx, "END\r\nX SetScale/P x, %g, %g, \"s\", %s_%i_%i_%i_%i\r\n", Toffset, dT, WAVENAME, k1+1,k2+1,k3+1,k4+1);
							fprintf(itx, "X SetScale y,0,0,\"%s\", %s_%i_%i_%i_%i\n", physdim, WAVENAME, k1+1,k2+1,k3+1,k4+1);
						}	

#ifdef NO_BI
#define _BI (BI[ns])
#else
#define _BI (hc->bi)
#endif
						// no need to check byte order because File.Endian is set and endian conversion is done in sread
						if ((DIV==1) && (gdftyp == hc->GDFTYP))	{
							uint16_t sz = GDFTYP_BITS[hc->GDFTYP]>>3;	
							memcpy(hdr->AS.rawdata + _BI + SPR * sz, hdr->AS.Header + DataPos, spr * sz);
						}
						else if (1) {
							double Cal = DataScaler * PhysDimScale(pdc) / hdr->CHANNEL[ns].Cal;
							assert(Cal==1.0 || hc->GDFTYP > 15); // when scaling changes, target data type is always float/double -> see above
							uint32_t k5,k6;
							switch (gdftyp) {
							case 3: 
								switch (hc->GDFTYP) {
								case 3: 
									for (k5 = 0; k5 < spr; ++k5) {
										int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(int16_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 2) = ival;
									}
									break;
								case 5: 
									for (k5 = 0; k5 < spr; ++k5) {
										int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(int32_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (int32_t)ival;
									}
									break;
								case 16: 
									for (k5 = 0; k5 < spr; ++k5) {
										int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (float)ival * Cal;
									}
									break;
								case 17: 
									for (k5 = 0; k5 < spr; ++k5) {
										int16_t ival = *(int16_t*)(hdr->AS.Header + DataPos + k5 * 2);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal;
									}
									break;
								}
								break;
							case 5:
								switch (hc->GDFTYP) {
								case 5: 
									for (k5 = 0; k5 < spr; ++k5) {
										int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(int32_t*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = ival;
									}
									break;
								case 16: 
									for (k5 = 0; k5 < spr; ++k5) {
										int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = (float)ival * Cal;
									}
									break;
								case 17: 
									for (k5 = 0; k5 < spr; ++k5) {
										int32_t ival = *(int32_t*)(hdr->AS.Header + DataPos + k5 * 4);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal;
									}
									break;
								}
								break;
							case 16:
								switch (hc->GDFTYP) {
								case 16: 
									for (k5 = 0; k5 < spr; ++k5) {
										float ival = *(float*)(hdr->AS.Header + DataPos + k5 * 4);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(float*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 4) = ival * Cal;
									}
									break;
								case 17: 
									for (k5 = 0; k5 < spr; ++k5) {
										float ival = *(float*)(hdr->AS.Header + DataPos + k5 * 4);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = (double)ival * Cal;
									}
									break;
								}
								break;
							case 17:
								switch (hc->GDFTYP) {
								case 17: 
									for (k5 = 0; k5 < spr; ++k5) {
										double ival = *(double*)(hdr->AS.Header + DataPos + k5 * 8);
										for (k6 = 0; k6 < DIV; ++k6) 
											*(double*)(hdr->AS.rawdata + _BI + (SPR + k5*DIV + k6) * 8) = ival * Cal;
									}
									break;
								}
								break;
							}
						}
#undef _BI
						pos += Sizes.Rec.Trace+4;

					}
					if (flagSweepSelected) SPR += spr * DIV;
				}
			}