df-like Utility to Estimate Data Folder Size

This utility routine computes a lower bound on the size of data folders and optionally their children using techniques discussed / implemented elsewhere on IgorExchange (c.f. FindBigWaves, SizeOfType). It is extended to handle text as well as numeric waves as the helper function wSize, and accounts for the wave note.

An optional summary of the traversed data folder tree with it's estimated size in MB can be printed to the history by passing the optional depth parameter.

If one does not care about error in estimating size of complex variables, dfSize can easily be made ThreadSafe, as indicated.

// dfSize: Given a data folder reference, estimates the size, in bytes, of its contents.
// This will be an underestimate, as it does not properly treat special waves such as DFREFs, etc.
// Wave sizes are estimated with wSize, and are subject to its limitations.
// If the optional depth parameter is specified with a positive integer, prints directory status updates
// up to depth from dfr with size in MB.
Function dfSize(dfr, [depth, curDepth])
	DFREF dfr
	Variable depth // print depth size updates
	Variable curDepth // current depth
	
	if(ParamIsDefault(depth))
		depth = NaN
	endif
	
	if(ParamIsDefault(curDepth))
		curDepth = 0
	endif
	
	DFREF dfSave = GetDataFolderDFR()
	
	SetDataFolder dfr
	
	Variable i
	Variable byteSum = 0
	String curName = ""
	Variable numDFs = CountObjectsDFR(dfr, 4)
	for(i = 0; i < numDFs; i += 1)
		curName = GetIndexedObjNameDFR(dfr, 4, i)
		DFREF curDF = $curName
		
		byteSum += dfSize(curDF, depth = depth, curDepth = curDepth + 1)
	endfor
	
	// Children are handled; do sum
	Variable nvarSiz = 0
	Variable wavSiz = 0
	Variable svarSiz = 0
	
	for(i = 0; i < CountObjectsDFR(dfr, 3); i += 1)
		curName = GetIndexedObjNameDFR(dfr, 3, i)
		SVAR curSVAR = $curName
		
		svarSiz += strlen(curSVAR)
	endfor
	
	// NVARS are always floating point, but might be complex
	nvarSiz += 4 * ItemsInList(VariableList("*", ";", 4)) + 8 * ItemsInList(VariableList("*", ";", 5))
	
// This would need to be enabled for a ThreadSafe implementation, should a means to test NVARs for complex-ness be found	
//	for(i = 0; i < CountObjectsDFR(dfr, 2); i += 1)
//		curName = GetIndexedObjNameDFR(dfr, 2, i)
//		
//		SVAR curNVAR = $curName
//		
//		nvarSiz += 4 
//	endfor
	
	for(i = 0; i < CountObjectsDFR(dfr, 1); i += 1)
		curName = GetIndexedObjNameDFR(dfr, 1, i)
		WAVE curWAV = $curName
		
		wavSiz += wSize(curWav)
	endfor
	
	byteSum += wavSiz + nvarSiz + svarSiz
	
	if(numType(depth) == 0)
		if(curDepth <= depth)
			Print GetDataFolder(1), byteSum / 2^20
		endif
	endif
	
	SetDataFolder dfSave
	
	return byteSum
End

// wSize: Returns a lower bound, in bytes, of an arbitrary wave's size based on its type and length. (Proprietary header
// information, dimension labels, etc. are not incorportated.)
ThreadSafe Function wSize(wav)
	WAVE wav
	String retName // Name of target wave
	
	WAVE nullWav // Null wave reference
	
	Variable typeCode
	Variable i, j, k, L
	Variable siz = 0
	Variable sizeOfType = 1
	Variable noteSize = 0
	
	switch(WaveType(wav, 1))
	case 0: // Null wave
		return 0
	case 3: // DF wave
	case 4: // WAVE wave
	
		// Do nothing
		return 0
	case 2:
		// Text wave
		// Cast wav as a text format
		WAVE/T txtWavCast = $GetWavesDataFolder(wav, 2)
		
		switch(WaveDims(txtWavCast))
		case 0:
			return 0
		case 1:
			for(i = 0; i < DimSize(txtWavCast, 0); i += 1)
				siz += strlen(txtWavCast[i])
			endfor
			
			break
		case 2:
			for(i = 0; i < DimSize(txtWavCast, 0); i += 1)
				for(j = 0; j < DimSize(txtWavCast, 1); j += 1)
					siz += strlen(txtWavCast[i][j])
				endfor
			endfor
			
			break
		case 3:
			for(i = 0; i < DimSize(txtWavCast, 0); i += 1)
				for(j = 0; j < DimSize(txtWavCast, 1); j += 1)
					for(k = 0; k < DimSize(txtWavCast, 2); k += 1)
						siz += strlen(txtWavCast[i][j][k])
					endfor
				endfor
			endfor
			
			break
		case 4:
			for(i = 0; i < DimSize(txtWavCast, 0); i += 1)
				for(j = 0; j < DimSize(txtWavCast, 1); j += 1)
					for(k = 0; k < DimSize(txtWavCast, 2); k += 1)
						for(L = 0; L < DimSize(txtWavCast, 3); L += 1)
							siz += strlen(txtWavCast[i][j][k][L])
						endfor
					endfor
				endfor
			endfor
			
			break
		endswitch
		
		// Don't forget the wave's note!
		noteSize = strlen(note(wav))
		return siz + noteSize
	endswitch

	// Numeric wave
	typeCode = WaveType(wav)
	
	// Need to return an appropriate WAVE reference type
	Variable waveIsComplex = typeCode & 0x01
	Variable waveIs32BitFloat = typeCode & 0x02
	Variable waveIs64BitFloat = typeCode & 0x04
	Variable waveIs8BitInteger = typeCode & 0x08
	Variable waveIs16BitInteger = typeCode & 0x10
	Variable waveIs32BitInteger = typeCode & 0x20
	Variable waveIsUnsigned = typeCode & 0x40
	
	// Determine wave type size multiplier
	// inspired by AG, WaveMetrics; igorexchange.com / node / 1845
	
	if(waveIsComplex)
		sizeOfType *= 2
	endif
	
	if(waveIs32BitFloat)
		sizeOfType *= 4
	elseif(waveIs64BitFloat)
		sizeOfType *= 8
	elseif(waveIs16BitInteger)
		sizeOfType *= 2
	elseif(waveIs32BitInteger)
		sizeofType *= 4
	endif
	
	// Don't forget the wave's note!
	noteSize = strlen(note(wav))
	
	return numpnts(wav) * sizeOfType + noteSize
End

Forum

Support

Gallery

Igor Pro 10

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More