def renameOutputFnWithEndtime(self, numSamples: int, tagsDict: Dict, x: Xml2BinState, filename: str):
     # rename the file that we just closed (if filename pattern has {endtime})
     if "{endtime}" in self.outputFnPattern:
         fmt = self.outputFnTimeFormatDict.get("starttime", None) if (self.outputFnTimeFormatDict is not None) else None
         tagsDict["starttime"] = dtTimestampFormat(self.headerStartDt, fmt)
         fmt = self.outputFnTimeFormatDict.get("exetime", None) if (self.outputFnTimeFormatDict is not None) else None
         tagsDict["exetime"] = dtTimestampFormat(x.timestampTm, fmt)
         endDt = self.headerStartDt + datetime.timedelta(seconds=int(numSamples / self.defaultSamplesPerSec))
         fmt = self.outputFnTimeFormatDict.get("endtime", None) if (self.outputFnTimeFormatDict is not None) else None
         tagsDict["endtime"] = dtTimestampFormat(endDt, fmt)
         if "tempendtime" in filename:
             original_filename = filename
             filename = getOutputFilename(self.outputDir, self.outputFnPattern, tagsDict, self.outputFnExt)
             if original_filename != filename:
                 os.rename(original_filename, filename)
             x.lastBinFilename = filename
Exemple #2
0
    def convert(self,
                xmlFile: str,
                tagsDict: Dict,
                x: Xml2BinState,
                print_processing_fn: bool = False):
        """
        convert to BIN file from XML
        """
        binFileOut = None
        filename = ""
        chanLabel = []
        tempChanInfo = []
        tempChanLabel = []
        tempChanLabel2Index = {}
        startWaveTm = datetime.datetime.min
        numSamples = 0
        totalNumSamplesWritten = 0
        firstBinFile = True
        firstMeasurement = True

        # array of parName, startTm, vitalFileOut, filename
        startVitalTm = datetime.datetime.min
        vitalFileInfoArr = []
        vitalParName2Info = {}

        # progress
        if (x.lastVitalFileInfoArr
                is not None) and (len(x.lastVitalFileInfoArr) > 0):
            for vinfo in x.lastVitalFileInfoArr:
                vs_parameter = vinfo["par"]
                vs_startTm = vinfo["startTm"]
                vitalFilename = vinfo["filename"]
                vitalFileOut = VitalFile(vitalFilename, "r+")
                vitalFileOut.open()
                vitalFileInfo = {
                    "par": vs_parameter,
                    "startTm": vs_startTm,
                    "vitalFileOut": vitalFileOut,
                    "filename": vitalFilename
                }
                vitalFileInfoArr.append(vitalFileInfo)
                vitalParName2Info[vs_parameter] = vitalFileInfo

        xml_unit = ""
        xml_bed = ""

        infilePath = Path(xmlFile)
        if not infilePath.exists():
            raise XmlConverterError("Cannot open file: {0}".format(xmlFile))
        else:
            if len(x.lastBinFilename) > 0:
                binFileOut = BinFile(x.lastBinFilename, "r+")
                binFileOut.open()
                binFileOut.readHeader()
                filename = x.lastBinFilename
                firstBinFile = False
                # copy BIN file's channel info
                chanLabel = []
                tempChanLabel = []
                chanLabel2Index = {}
                tempChanLabel2Index = {}
                idx = 0
                for c in binFileOut.channels:
                    chanLabel.append(c.Title)
                    chanLabel2Index[c.Title] = idx
                    tempChanLabel.append(c.Title)
                    tempChanLabel2Index[c.Title] = idx
                    idx += 1
                self.header = binFileOut.header
                second = int(math.floor(self.header.Second))
                microsecond = int(
                    (self.header.Second - math.floor(self.header.Second)) *
                    100)
                self.headerStartDt = datetime.datetime(
                    self.header.Year, self.header.Month, self.header.Day,
                    self.header.Hour, self.header.Minute, second, microsecond)
                numSamples = self.header.SamplesPerChannel
            # end-if len(x.lastBinFilename)
            if print_processing_fn:
                print("Processing XML file: {0}".format(infilePath.name))
            tree = ET.parse(xmlFile)
            root = tree.getroot()
            # print("root tag = {0}".format(root.tag))
            if root.tag == "BedMasterEx":
                for child1 in root:
                    if child1.tag == "FileInfo":
                        for child3 in child1:
                            if child3.tag == "Unit":
                                xml_unit = child3.text
                            elif child3.tag == "Bed":
                                xml_bed = child3.text
                    if child1.tag == "Segment":
                        for child3 in child1:
                            if child3.tag == "Waveforms":
                                collectionTime, collectionTimeUTC = self.processWaveforms(
                                    child3)
                                collectionTimeDt = parsetime(collectionTime)
                                tempChanInfo = []
                                tempChanLabel = []
                                tempChanLabel2Index = {}
                                if self.header is None:
                                    self.headerStartDt = collectionTimeDt
                                    self.header = CFWBINARY()
                                    self.header.setValue(
                                        1.0 / self.defaultSamplesPerSec,
                                        collectionTimeDt.year,
                                        collectionTimeDt.month,
                                        collectionTimeDt.day,
                                        collectionTimeDt.hour,
                                        collectionTimeDt.minute,
                                        collectionTimeDt.second, 0, 0)
                                # print(collectionTime, collectionTimeUTC)
                                idx = 0
                                for child4 in child3:
                                    if (child4.tag == "WaveformData"):
                                        ID, channel, hz, points, uom, wave = self.processWaveformData(
                                            child4)
                                        if self.inChannelPatternList(channel):
                                            # print(channel, wave, points, pointsBytes, min_, max_, offset, gain, hz)
                                            wavedata = self.decodeWave(wave)
                                            # print(wavedata)
                                            if self.defaultSamplesPerSec != hz:
                                                wavedata = fixsamplingarr(
                                                    wavedata, hz,
                                                    self.defaultSamplesPerSec)
                                            tempChanInfo.append({
                                                "label": channel,
                                                "data": wavedata,
                                                "points": points,
                                                "hz": hz,
                                                "uom": uom
                                            })
                                            tempChanLabel.append(channel)
                                            tempChanLabel2Index[channel] = idx
                                            idx += 1
                                # end-for child4
                                if (firstBinFile is True) or (
                                        len(tempChanLabel) > 0
                                        and self.channelChanged(
                                            chanLabel, tempChanLabel)):
                                    if firstBinFile is False:
                                        binFileOut.close()
                                        binFileOut = None
                                        # rename the file that we just closed (if filename pattern has {endtime})
                                        self.renameOutputFnWithEndtime(
                                            numSamples, tagsDict, x, filename)
                                        if not (x.lastBinFilename
                                                in self.outputFileSet):
                                            self.outputFileSet.add(
                                                x.lastBinFilename)
                                            self.outputFileList.append(
                                                x.lastBinFilename)
                                        # reset new headerStartDt
                                        self.headerStartDt = collectionTimeDt
                                        self.header.setValue(
                                            1.0 / self.defaultSamplesPerSec,
                                            collectionTimeDt.year,
                                            collectionTimeDt.month,
                                            collectionTimeDt.day,
                                            collectionTimeDt.hour,
                                            collectionTimeDt.minute,
                                            collectionTimeDt.second, 0, 0)
                                    firstBinFile = False
                                    self.header.NChannels = len(tempChanInfo)
                                    fmt = self.outputFnTimeFormatDict.get(
                                        "starttime",
                                        None) if (self.outputFnTimeFormatDict
                                                  is not None) else None
                                    tagsDict["starttime"] = dtTimestampFormat(
                                        self.headerStartDt, fmt)
                                    fmt = self.outputFnTimeFormatDict.get(
                                        "exetime",
                                        None) if (self.outputFnTimeFormatDict
                                                  is not None) else None
                                    tagsDict["exetime"] = dtTimestampFormat(
                                        x.timestampTm, fmt)
                                    # we do not know the end at this point
                                    tagsDict["endtime"] = "tempendtime" + str(
                                        random.randint(10000, 100000))
                                    filename = getOutputFilename(
                                        self.outputDir, self.outputFnPattern,
                                        tagsDict, self.outputFnExt)
                                    x.lastBinFilename = filename
                                    binFileOut = BinFile(filename, "w")
                                    binFileOut.open()
                                    binFileOut.setHeader(self.header)
                                    chanData = []
                                    chanLabel = []
                                    for cinfo in tempChanInfo:
                                        label = cinfo["label"]
                                        cSettingInfo = self.getChannelInfo(
                                            label)
                                        if cSettingInfo is not None:
                                            uom = cSettingInfo.get(
                                                "uom", cinfo.get("uom", ""))
                                            rangeLow = cSettingInfo.get(
                                                "rangeLow", 0)
                                            rangeHigh = cSettingInfo.get(
                                                "rangeHigh", 100)
                                            offset = cSettingInfo.get(
                                                "offset", 0)
                                            scale = cSettingInfo.get(
                                                "scale", 1)
                                        else:
                                            uom = cinfo.get("uom", "")
                                            rangeLow = 0
                                            rangeHigh = 100
                                            offset = 0
                                            scale = 1
                                        channel = CFWBCHANNEL()
                                        channel.setValue(
                                            label, uom, scale, offset,
                                            rangeLow, rangeHigh)
                                        binFileOut.addChannel(channel)
                                        chanData.append(cinfo["data"])
                                        chanLabel.append(label)
                                    binFileOut.writeHeader()
                                    firstMeasurement = False
                                    numSamples = binFileOut.writeChannelData(
                                        chanData)
                                    totalNumSamplesWritten += numSamples
                                    binFileOut.updateSamplesPerChannel(
                                        numSamples, True)
                                elif len(tempChanInfo) > 0:
                                    chanData = []
                                    chanLabel = []
                                    for cinfo in tempChanInfo:
                                        label = cinfo["label"]
                                        chanData.append(cinfo["data"])
                                        chanLabel.append(label)
                                    # gap handling
                                    endDt = self.headerStartDt + datetime.timedelta(
                                        seconds=int(numSamples /
                                                    self.defaultSamplesPerSec))
                                    gap = collectionTimeDt - endDt
                                    actualGapInSec = int(gap.total_seconds())
                                    if (not self.ignoreGapBetweenSegs
                                        ) and firstMeasurement:
                                        gapInSec = actualGapInSec
                                    elif not self.ignoreGap:
                                        gapInSec = actualGapInSec
                                    else:
                                        gapInSec = 0
                                    if self.warningOnGaps and (gapInSec != 0):
                                        print(
                                            "Waveforms CollectionTime: {0} shows gap (or overlap) = {1} secs"
                                            .format(collectionTime, gapInSec))
                                    firstMeasurement = False
                                    numSamplesWritten = binFileOut.writeChannelData(
                                        chanData, self.defaultSamplesPerSec,
                                        gapInSec)
                                    totalNumSamplesWritten += numSamplesWritten
                                    numSamples = numSamplesWritten + binFileOut.header.SamplesPerChannel
                                    binFileOut.header.SamplesPerChannel = numSamples
                                    self.header.SamplesPerChannel = numSamples
                                    binFileOut.updateSamplesPerChannel(
                                        numSamples, True)
                                # end-if firstBinFile
                            # end-if "measurement"
                            if child3.tag == "VitalSigns":
                                collectionTime, collectionTimeUTC = self.processVitalSigns(
                                    child3)
                                collectionTimeDt = parsetime(collectionTime)
                                vs_parameter = ""
                                vs_time = ""
                                vs_value = ""
                                vs_uom = ""
                                vs_alarmLimitLow = ""
                                vs_alarmLimitHigh = ""
                                for child4 in child3:
                                    if (child4.tag == "VitalSign"):
                                        vs_parameter, vs_time, vs_value, vs_uom, vs_alarmLimitLow, vs_alarmLimitHigh = self.processVitalSign(
                                            child4)
                                        # print(vs_parameter)
                                    if (vs_parameter is not None
                                        ) and len(vs_parameter) > 0:
                                        vitalFileInfo = None
                                        if vs_parameter in vitalParName2Info:
                                            vitalFileInfo = vitalParName2Info.get(
                                                vs_parameter)
                                        else:
                                            vs_time_dt = parsetime(vs_time)
                                            fmt = self.outputFnTimeFormatDict.get(
                                                "starttime", None) if (
                                                    self.outputFnTimeFormatDict
                                                    is not None) else None
                                            tagsDict[
                                                "starttime"] = dtTimestampFormat(
                                                    vs_time_dt, fmt)
                                            fmt = self.outputFnTimeFormatDict.get(
                                                "exetime", None) if (
                                                    self.outputFnTimeFormatDict
                                                    is not None) else None
                                            tagsDict[
                                                "exetime"] = dtTimestampFormat(
                                                    x.timestampTm, fmt)
                                            # we do not know the end at this point
                                            tagsDict[
                                                "endtime"] = "0000"  # "tempendtime" + str(random.randint(10000, 100000))
                                            # array of parName, startTm, vitalFileOut, filename
                                            vitalFilename = getOutputFilename(
                                                self.outputDir,
                                                self.outputFnPattern + "_" +
                                                vs_parameter, tagsDict,
                                                "vital")
                                            vitalFileOut = VitalFile(
                                                vitalFilename, "w")
                                            vitalFileOut.open()
                                            startVitalTm = vs_time_dt
                                            vitalFileInfo = {
                                                "par": vs_parameter,
                                                "startTm": startVitalTm,
                                                "vitalFileOut": vitalFileOut,
                                                "filename": vitalFilename
                                            }
                                            vitalFileInfoArr.append(
                                                vitalFileInfo)
                                            vitalParName2Info[
                                                vs_parameter] = vitalFileInfo
                                            vs_header = VITALBINARY(
                                                vs_parameter, vs_uom, xml_unit,
                                                xml_bed, startVitalTm.year,
                                                startVitalTm.month,
                                                startVitalTm.day,
                                                startVitalTm.hour,
                                                startVitalTm.minute,
                                                startVitalTm.second)
                                            vitalFileOut.setHeader(vs_header)
                                            vitalFileOut.writeHeader()
                                        if vitalFileInfo is not None:
                                            vs_value_num = DEFAULT_VS_LIMIT_LOW
                                            try:
                                                vs_value_num = float(vs_value)
                                            except:
                                                pass
                                            vs_time_dt = parsetime(vs_time)
                                            vs_offset_num = (
                                                vs_time_dt -
                                                vitalFileInfo["startTm"]
                                            ).total_seconds()
                                            vs_low_num = DEFAULT_VS_LIMIT_LOW
                                            try:
                                                vs_low_num = float(
                                                    vs_alarmLimitLow)
                                            except:
                                                pass
                                            vs_high_num = DEFAULT_VS_LIMIT_HIGH
                                            try:
                                                vs_high_num = float(
                                                    vs_alarmLimitHigh)
                                            except:
                                                pass
                                            vitalFileOut = vitalFileInfo[
                                                "vitalFileOut"]
                                            vitalFileOut.writeVitalData(
                                                vs_value_num, vs_offset_num,
                                                vs_low_num, vs_high_num)
                # end-for child1
            # end-if root
        # end-if
        if binFileOut is not None:
            binFileOut.close()
            binFileOut = None
            # rename the file that we just closed (if filename pattern has {endtime})
            self.renameOutputFnWithEndtime(numSamples, tagsDict, x, filename)
            if not (x.lastBinFilename in self.outputFileSet):
                self.outputFileSet.add(x.lastBinFilename)
                self.outputFileList.append(x.lastBinFilename)
        for vf in vitalFileInfoArr:
            vitalFileOut = vf["vitalFileOut"]
            if vitalFileOut is not None:
                vitalFileOut.close()
                vf["vitalFileOut"] = None
            x.addOrUpdateLastVitalFileInfo(vf["par"], vf["startTm"],
                                           vf["filename"])

        return totalNumSamplesWritten
Exemple #3
0
def runApp(flow: str, srcFile: str, srcDir: str, dstDir: str):
    timestampTm = datetime.now()
    tagsDict = {
        "id1": g_id1,
        "id2": g_id2,
        "id3": g_id3,
        "id4": g_id4,
        "id5": g_id5
    }
    xmlconverter = None

    if flow == "file":
        xml2BinState = Xml2BinState()
        xml2BinState.setTimestampTm(timestampTm)
        if g_converter_type == "bernoulli":
            xmlconverter = XmlConverterForGE(
                dstDir, g_output_fn_pattern, g_output_fn_ext,
                int(g_sampling_rate), g_channel_pattern_list,
                g_channel_info_list, g_ignore_gap, g_ignore_gap_between_segs,
                g_warning_on_gaps, g_output_fn_time_format_dict)
        elif g_converter_type == "bedmaster":
            xmlconverter = XmlConverterForBedMaster(
                dstDir, g_output_fn_pattern, g_output_fn_ext,
                int(g_sampling_rate), g_channel_pattern_list,
                g_channel_info_list, g_ignore_gap, g_ignore_gap_between_segs,
                g_warning_on_gaps, g_output_fn_time_format_dict)
        xmlconverter.convert(srcFile,
                             tagsDict,
                             xml2BinState,
                             print_processing_fn=True)
        xmlconverter.renameChannels(print_rename_details=True)
        return 0
    elif flow == "dir":
        numFilesProcessed = 0
        xml2BinState = Xml2BinState()
        xml2BinState.setTimestampTm(timestampTm)
        if g_converter_type == "bernoulli":
            xmlconverter = XmlConverterForGE(
                dstDir, g_output_fn_pattern, g_output_fn_ext,
                int(g_sampling_rate), g_channel_pattern_list,
                g_channel_info_list, g_ignore_gap, g_ignore_gap_between_segs,
                g_warning_on_gaps, g_output_fn_time_format_dict)
        elif g_converter_type == "bedmaster":
            xmlconverter = XmlConverterForBedMaster(
                dstDir, g_output_fn_pattern, g_output_fn_ext,
                int(g_sampling_rate), g_channel_pattern_list,
                g_channel_info_list, g_ignore_gap, g_ignore_gap_between_segs,
                g_warning_on_gaps, g_output_fn_time_format_dict)
        for file in sorted(os.listdir(srcDir)):
            # debug
            fp = os.path.join(srcDir, file)
            ext = os.path.splitext(fp)[1] if len(
                os.path.splitext(fp)) == 2 else ""
            if ext == ".xml":
                xmlconverter.clearState()
                xmlconverter.convert(fp,
                                     tagsDict,
                                     xml2BinState,
                                     print_processing_fn=True)
                numFilesProcessed += 1
        xmlconverter.renameChannels(print_rename_details=True)
        print("Number of XML files processed = {0}".format(numFilesProcessed))
        return 0
    elif flow == "stp":
        # need to add date-range option for processing
        ext_exe = str(g_converter_options.get("stptools_exe", ""))
        ext_param = str(g_converter_options.get("stptools_param", ""))
        keep_temp_file = bool(g_converter_options.get("keep_temp_files",
                                                      False))
        numSegmentsPerBatch = int(
            g_converter_options.get("num_segments_per_batch", 500))
        numSegmentsProcessed = 0
        xml2BinState = Xml2BinState()
        xml2BinState.setTimestampTm(timestampTm)
        if g_converter_type == "bedmaster":
            xmlconverter = XmlConverterForBedMaster(
                dstDir, g_output_fn_pattern, g_output_fn_ext,
                int(g_sampling_rate), g_channel_pattern_list,
                g_channel_info_list, g_ignore_gap, g_ignore_gap_between_segs,
                g_warning_on_gaps, g_output_fn_time_format_dict)
        startSegment = 0
        endSegment = startSegment + numSegmentsPerBatch - 1
        if (ext_exe is None) or (len(ext_exe) == 0):
            print("ERROR: stptools_exe option not set!")
            return 1
        hasSegments = True
        useTime = (g_stime is not None) and (g_etime is not None)
        time_step = timedelta(days=1)
        current_stime = g_stime
        current_etime = g_stime
        numSamplesWritten = 0
        if useTime:
            current_etime = g_stime + time_step
            if current_etime > g_etime:
                current_etime = g_etime
        while ((not useTime)
               and hasSegments) or (useTime and (current_stime < g_etime) and
                                    (current_stime < current_etime)):
            basefn = Path(srcFile).stem
            xmlOutputFn = "{0}_{1}_{2}_wf.xml".format(
                basefn, dtTimestampFormat(timestampTm), startSegment)
            xmlOutputFullFn = execute_ext(ext_exe, srcFile, ext_param,
                                          xmlOutputFn, startSegment,
                                          endSegment, current_stime,
                                          current_etime)
            xmlProcesingStarttime = datetime.now()
            if Path(xmlOutputFullFn).exists():
                if not useTime:
                    print("Processing XML from segment {0} to segment {1}...".
                          format(startSegment, endSegment))
                else:
                    print("Processing XML from {0} to {1}...".format(
                        current_stime.strftime("%m/%d/%Y %I:%M:%S %p"),
                        current_etime.strftime("%m/%d/%Y %I:%M:%S %p")))
                xmlconverter.clearState()
                numSamplesWritten = xmlconverter.convert(
                    xmlOutputFullFn,
                    tagsDict,
                    xml2BinState,
                    print_processing_fn=True)
                xmlProcessingEndtime = datetime.now()
                xmlProcessingElapsedtime = xmlProcessingEndtime - xmlProcesingStarttime
                if numSamplesWritten == 0:
                    print("No more data segments for processing.")
                print("Processing XML takes {0}".format(
                    elapsedFormat(xmlProcessingElapsedtime.total_seconds(),
                                  totalSecondsOnly=True)))
                if not keep_temp_file:
                    os.remove(xmlOutputFullFn)
            startSegment = endSegment + 1
            endSegment = startSegment + numSegmentsPerBatch - 1
            numSegmentsProcessed += numSegmentsPerBatch
            hasSegments = (numSamplesWritten > 0)
            if useTime:
                current_stime = current_etime
                current_etime = current_stime + time_step
                if current_etime > g_etime:
                    current_etime = g_etime
        xmlconverter.renameChannels(print_rename_details=True)
        print("Done")
    def convert(self, xmlFile: str, tagsDict: Dict, x: Xml2BinState, print_processing_fn: bool = False):
        """
        convert to BIN file from XML
        """
        binFileOut = None
        filename = ""
        chanLabel = []
        tempChanInfo = []
        tempChanLabel = []
        tempChanLabel2Index = {}
        startWaveTm = datetime.datetime.min
        numSamples = 0
        totalNumSamplesWritten = 0
        firstBinFile = True
        firstMeasurement = True

        infilePath = Path(xmlFile)
        if not infilePath.exists():
            raise XmlConverterError("Cannot open file: {0}".format(xmlFile))
        else:
            if len(x.lastBinFilename) > 0:
                binFileOut = BinFile(x.lastBinFilename, "r+")
                binFileOut.open()
                binFileOut.readHeader()
                filename = x.lastBinFilename
                firstBinFile = False
                # copy BIN file's channel info
                chanLabel = []
                tempChanLabel = []
                chanLabel2Index = {}
                tempChanLabel2Index = {}
                idx = 0
                for c in binFileOut.channels:
                    chanLabel.append(c.Title)
                    chanLabel2Index[c.Title] = idx
                    tempChanLabel.append(c.Title)
                    tempChanLabel2Index[c.Title] = idx
                    idx += 1
                self.header = binFileOut.header
                second = int(math.floor(self.header.Second))
                microsecond = int((self.header.Second - math.floor(self.header.Second)) * 100)
                self.headerStartDt = datetime.datetime(self.header.Year, self.header.Month, self.header.Day,
                                                       self.header.Hour, self.header.Minute, second, microsecond)
                numSamples = self.header.SamplesPerChannel
            # end-if len(x.lastBinFilename)
            if print_processing_fn:
                print("Processing XML file: {0}".format(infilePath.name))
            tree = ET.parse(xmlFile)
            root = tree.getroot()
            # print("root tag = {0}".format(root.tag))
            if root.tag == "cpcArchive":
                for child1 in root:
                    if child1.tag == "cpc":
                        cpc_datetime, cpc_tzoffset = self.processCpc(child1)
                        for child2 in child1:
                            if child2.tag == "device":
                                for child3 in child2:
                                    if child3.tag == "measurements":
                                        pollTime, tz_offset = self.processMeassurement(child3)
                                        pollTimeDt = parsetime(pollTime.replace('T', ' ').replace('Z', ''))
                                        if pollTimeDt is None:
                                            # use cpc_datetime if measurement does not have PollTime
                                            cpc_dt1 = cpc_datetime
                                            cpc_dt_parts = cpc_dt1.split('.', 2)
                                            if len(cpc_dt_parts) > 1:
                                                cpc_dt1 = cpc_dt_parts[0]
                                            pollTimeDt = parsetime(cpc_dt1.replace('T', ' ').replace('Z', ''))
                                        # if still cannot get a valid PollTime
                                        # just skip for now... maybe need to print warning
                                        if pollTimeDt is None:
                                            continue
                                        else:
                                            tempChanInfo = []
                                            tempChanLabel = []
                                            tempChanLabel2Index = {}
                                            if self.header is None:
                                                self.headerStartDt = pollTimeDt
                                                self.header = CFWBINARY()
                                                self.header.setValue(1.0 / self.defaultSamplesPerSec, pollTimeDt.year, pollTimeDt.month,
                                                                     pollTimeDt.day, pollTimeDt.hour, pollTimeDt.minute, pollTimeDt.second, 0, 0)
                                        # print(pollTime, tz_offset)
                                        idx = 0
                                        for child4 in child3:
                                            if (child4.tag == "mg"):
                                                channel, wave, points, pointsBytes, min_, max_, offset, gain, hz = self.processMg(child4)
                                                if self.inChannelPatternList(channel):
                                                    # print(channel, wave, points, pointsBytes, min_, max_, offset, gain, hz)
                                                    wavedata = self.decodeWave(wave)
                                                    # print(wavedata)
                                                    if self.defaultSamplesPerSec != hz:
                                                        wavedata = fixsamplingarr(wavedata, hz, self.defaultSamplesPerSec)
                                                    tempChanInfo.append({"label": channel, "data": wavedata, "points": points, "pointsBytes": pointsBytes,
                                                                         "min": min_, "max": max_, "offset": offset, "gain": gain, "hz": hz})
                                                    tempChanLabel.append(channel)
                                                    tempChanLabel2Index[channel] = idx
                                                    idx += 1
                                        # end-for child4
                                        # progress
                                        if (firstBinFile is True) or (len(tempChanLabel) > 0 and self.channelChanged(chanLabel, tempChanLabel)):
                                            if firstBinFile is False:
                                                binFileOut.close()
                                                binFileOut = None
                                                # rename the file that we just closed (if filename pattern has {endtime})
                                                self.renameOutputFnWithEndtime(numSamples, tagsDict, x, filename)
                                                if not (x.lastBinFilename in self.outputFileSet):
                                                    self.outputFileSet.add(x.lastBinFilename)
                                                    self.outputFileList.append(x.lastBinFilename)
                                                # reset new headerStartDt
                                                self.headerStartDt = pollTimeDt
                                                self.header.setValue(1.0 / self.defaultSamplesPerSec, pollTimeDt.year, pollTimeDt.month,
                                                                     pollTimeDt.day, pollTimeDt.hour, pollTimeDt.minute, pollTimeDt.second, 0, 0)
                                            firstBinFile = False
                                            self.header.NChannels = len(tempChanInfo)
                                            fmt = self.outputFnTimeFormatDict.get("starttime", None) if (self.outputFnTimeFormatDict is not None) else None
                                            tagsDict["starttime"] = dtTimestampFormat(self.headerStartDt, fmt)
                                            fmt = self.outputFnTimeFormatDict.get("exetime", None) if (self.outputFnTimeFormatDict is not None) else None
                                            tagsDict["exetime"] = dtTimestampFormat(x.timestampTm, fmt)
                                            # we do not know the end at this point
                                            tagsDict["endtime"] = "tempendtime" + str(random.randint(10000, 100000))
                                            filename = getOutputFilename(self.outputDir, self.outputFnPattern, tagsDict, self.outputFnExt)
                                            x.lastBinFilename = filename
                                            binFileOut = BinFile(filename, "w")
                                            binFileOut.open()
                                            binFileOut.setHeader(self.header)
                                            chanData = []
                                            chanLabel = []
                                            for cinfo in tempChanInfo:
                                                label = cinfo["label"]
                                                cSettingInfo = self.getChannelInfo(label)
                                                if cSettingInfo is not None:
                                                    uom = cSettingInfo.get("uom", "")
                                                    rangeLow = cSettingInfo.get("rangeLow", cinfo["min"])
                                                    rangeHigh = cSettingInfo.get("rangeHigh", cinfo["max"])
                                                    offset = cSettingInfo.get("offset", cinfo["offset"])
                                                    scale = cSettingInfo.get("scale", cinfo["gain"])
                                                else:
                                                    uom = ""
                                                    rangeLow = cinfo["min"]
                                                    rangeHigh = cinfo["max"]
                                                    offset = cinfo["offset"]
                                                    scale = cinfo["gain"]
                                                channel = CFWBCHANNEL()
                                                channel.setValue(label, uom, scale, offset, rangeLow, rangeHigh)
                                                binFileOut.addChannel(channel)
                                                chanData.append(cinfo["data"])
                                                chanLabel.append(label)
                                            binFileOut.writeHeader()
                                            firstMeasurement = False
                                            numSamples = binFileOut.writeChannelData(chanData)
                                            totalNumSamplesWritten += numSamples
                                            binFileOut.updateSamplesPerChannel(numSamples, True)
                                        elif len(tempChanInfo) > 0:
                                            chanData = []
                                            chanLabel = []
                                            for cinfo in tempChanInfo:
                                                label = cinfo["label"]
                                                chanData.append(cinfo["data"])
                                                chanLabel.append(label)
                                            # gap handling
                                            endDt = self.headerStartDt + datetime.timedelta(seconds=int(numSamples / self.defaultSamplesPerSec))
                                            gap = pollTimeDt - endDt
                                            actualGapInSec = int(gap.total_seconds())
                                            if (not self.ignoreGapBetweenSegs) and firstMeasurement:
                                                gapInSec = actualGapInSec
                                            elif not self.ignoreGap:
                                                gapInSec = actualGapInSec
                                            else:
                                                gapInSec = 0
                                            if self.warningOnGaps and (gapInSec != 0):
                                                if pollTime is None or len(pollTime) == 0:
                                                    print("cpc datetime: {0} shows gap (or overlap) = {1} secs".format(cpc_datetime, gapInSec))
                                                else:
                                                    print("Measurement POLLTIME: {0} shows gap (or overlap) = {1} secs".format(pollTime, gapInSec))
                                            firstMeasurement = False
                                            numSamplesWritten = binFileOut.writeChannelData(chanData, self.defaultSamplesPerSec, gapInSec)
                                            totalNumSamplesWritten += numSamplesWritten
                                            numSamples = numSamplesWritten + binFileOut.header.SamplesPerChannel
                                            binFileOut.header.SamplesPerChannel = numSamples
                                            self.header.SamplesPerChannel = numSamples
                                            binFileOut.updateSamplesPerChannel(numSamples, True)
                                        # end-if firstBinFile
                                    # end-if "measurement"
                                # end-for child3
                        # end-for child2
                # end-for child1
            # end-if root
        # end-if
        if binFileOut is not None:
            binFileOut.close()
            binFileOut = None
            # rename the file that we just closed (if filename pattern has {endtime})
            self.renameOutputFnWithEndtime(numSamples, tagsDict, x, filename)
            if not (x.lastBinFilename in self.outputFileSet):
                self.outputFileSet.add(x.lastBinFilename)
                self.outputFileList.append(x.lastBinFilename)
        return totalNumSamplesWritten