Read text file in matlab - matlab

I am trying to read a text file in matlab. I have done this, but I don't know how to store this value in an array.
My text file contains data like this:
01 ff 02 ff
02 ff 02 ff
03 ff 02 ff
file = fopen(fpath,'r');
allData = textscan(file, '%s', 'delimiter','\n');
for i = 1:491003
newData = allData{1,1}{i};
end
I want to store each row in separate array, something like this:
a[0] = '01 ff 02 ff'
a[1] = '02 ff 02 ff'
Once I have such arrays, I want to access each value of this arrays, something like this:
a[0][0] = 01, a[0][1] = ff, a[0][2] = 02..
a[1][0] = 02, a[1][1] = ff, a[1][2] = 02..
I am new to MATLAB and couldn't find much help myself. Plz help.

allData = textscan(file, '%s %s %s %s');
allData will be a cell array

Ok, I finally got my answer. I used "Import Data" facility which is available in Matlab 2013. It really helps you to get your data in the way you want.
Cheers.

Related

CSV file export in MATLAB adding new lines

I'm trying to take in a complex csv file in MATLAB and edit/rearrange it. I used tableread to pull out the numerical data that I then manipulated. Afterwards I aimed to take the first 52 rows of text metadata, add three more rows then combine with the numerical data and output as a csv file.
However, I can't seem to find a way to work with the text metadata rows that doesn't ultimately add new lines between them when output.
e.g. this is how my csv outputs:
#HEADER
,,,,,,
Instrument, Data Processed Analysis
,,,,,
Version,1.3.1,1.25
,,,,
Created,Monday, August 16, 2021 3:13:38 PM
,,,
Filename,D5-116.NGXDP
,,,,,
When it should look like:
#HEADER
NGX, Data Processed Analysis
Version,1.3.1,1.25
Created,Monday, August 16, 2021 3:13:38 PM
Filename,D5-116.NGXDP
Here is my code:
`
close
clear
fileName = 'D5-116.NGXDP';
fileOut = fileName(1:end-6);
fileOut = append(fileOut, '.csv');
eEnergy = 1.602176634e-19; %electron energy in coulombs
resisTor = 1e11; %Resistor value for EM
%% Reading and Edit Mass Data - this is too hardcoded right now
T = readtable(fileName, 'FileType', 'text');
T = T{:,:}; %convert from table to matrix
dataOrg(:,1:3) = T(1087:1236, 1:3); %cycle:time:Ar
dataOrg(:,4) = T(935:1084, 3); %39
dataOrg(:,5) = T(783:932, 3); %38
dataOrg(:,6) = T(631:780, 3); %37
dataOrg(:,7) = T(479:628, 3); %36
dataOrg(:,7) = dataOrg(:,7) * eEnergy * resisTor; %36Ar - convert CPS to V
dataOrg(:,3:7) = dataOrg(:,3:7) * 1000; %Convert all to mV
%% Reading the metadata from the file
T2 = fopen(fileName);
metaData = fread(T2, '*char')'; %read content
fclose(T2);
results = strsplit(metaData, '\n'); %split the char data by entry spaces
metaNeat = results(:,1:52)'; %Takes the metadata prior to #collectors
metaNeat(end+1, 1) = {'Blocks, 1'}; %added data
metaNeat(end+1, 1) = {'Cycles, 150'}; %added data
metaNeat(end+1, 1) = {'Cycle, Time, 40, 39, 38, 37, 36'};
for n = 1:length(metaNeat) %scan each row, if there is a comma split them
if contains(metaNeat(n,1), ',') == 1
tempMeta = split(metaNeat(n,1), ',')';
metaNeat(n,1:size(tempMeta, 2)) = tempMeta;
clear tempMeta
end
end
outPut = metaNeat; %metadata section
outPut(end+1:(end+150), 1:7) = num2cell(dataOrg); %mass value section
writecell(outPut,fileOut,'Delimiter',',', 'FileType', 'text')
I'm sure there is a way to do this in three lines of course. My guess is that the strsplit function I'm using to separate the char cell into multiple rows is preserving the \n value. The added lines (e.g. Blocks, 1) do not show gaps in the csv file. Any tips or advice would be appreciated.
Thanks for your time,

SBData is wrong when SBValue comes from a Swift Dictionary

I'm trying to write a Python function to format a Foundation.Decimal, for use as a type summarizer. I posted it in this answer. I'll also include it at the bottom of this answer, with extra debug prints.
I've now discovered a bug, but I don't know if the bug is in my function, or in lldb, or possibly in the Swift compiler.
Here's a transcript that demonstrates the bug. I load my type summarizer in ~/.lldbinit, so the Swift REPL uses it.
:; xcrun swift
registering Decimal type summaries
Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance.
1> import Foundation
2> let dec: Decimal = 7
dec: Decimal = 7
Above, the 7 in the debugger output is from my type summarizer and is correct.
3> var dict = [String: Decimal]()
dict: [String : Decimal] = 0 key/value pairs
4> dict["x"] = dec
5> dict["x"]
$R0: Decimal? = 7
Above, the 7 is again from my type summarizer, and is correct.
6> dict
$R1: [String : Decimal] = 1 key/value pair {
[0] = {
key = "x"
value = 0
}
}
Above, the 0 (in value = 0) is from my type summarizer, and is incorrect. It should be 7.
So why is it zero? My Python function is given an SBValue. It calls GetData() on the SBValue to get an SBData. I added debug prints to the function to print the bytes in the SBData, and also to print the result of sbValue.GetLoadAddress(). Here's the transcript with these debug prints:
:; xcrun swift
registering Decimal type summaries
Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance.
1> import Foundation
2> let dec: Decimal = 7
dec: Decimal = loadAddress: ffffffffffffffff
data: 00 21 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7
Above, we can see that the load address is bogus, but the bytes of the SBData are correct (byte 1, 21, contains the length and flags; byte 4, '07', is the first byte of the significand).
3> var dict = [String: Decimal]()
dict: [String : Decimal] = 0 key/value pairs
4> dict["x"] = dec
5> dict
$R0: [String : Decimal] = 1 key/value pair {
[0] = {
key = "x"
value = loadAddress: ffffffffffffffff
data: 00 00 00 00 00 21 00 00 07 00 00 00 00 00 00 00 00 00 00 00
0
}
}
Above, we can see that the load address is still bogus, and now the bytes of the SBData are incorrect. The SBData still contains 20 bytes (the correct number for a Foundation.Decimal, aka NSDecimal), but now four 00 bytes have been inserted at the front and the last four bytes have been dropped.
So here are my specific questions:
Am I using the lldb API incorrectly, and thus getting wrong answers? If so, what am I doing wrong and how should I correct it?
If I'm using the lldb API correctly, then is this a bug in lldb, or is the Swift compiler emitting incorrect metadata? How can I figure out which tool has the bug? (Because if it's a bug in one of the tools, I'd like to file a bug report.)
If it's a bug in lldb or Swift, how can I work around the problem so I can format a Decimal correctly when it's part of a Dictionary?
Here is my type formatter, with debug prints:
# Decimal / NSDecimal support for lldb
#
# Put this file somewhere, e.g. ~/.../lldb/Decimal.py
# Then add this line to ~/.lldbinit:
# command script import ~/.../lldb/Decimal.py
import lldb
def stringForDecimal(sbValue, internal_dict):
from decimal import Decimal, getcontext
print(' loadAddress: %x' % sbValue.GetLoadAddress())
sbData = sbValue.GetData()
if not sbData.IsValid():
raise Exception('unable to get data: ' + sbError.GetCString())
if sbData.GetByteSize() != 20:
raise Exception('expected data to be 20 bytes but found ' + repr(sbData.GetByteSize()))
sbError = lldb.SBError()
exponent = sbData.GetSignedInt8(sbError, 0)
if sbError.Fail():
raise Exception('unable to read exponent byte: ' + sbError.GetCString())
flags = sbData.GetUnsignedInt8(sbError, 1)
if sbError.Fail():
raise Exception('unable to read flags byte: ' + sbError.GetCString())
length = flags & 0xf
isNegative = (flags & 0x10) != 0
debugString = ''
for i in range(20):
debugString += ' %02x' % sbData.GetUnsignedInt8(sbError, i)
print(' data:' + debugString)
if length == 0 and isNegative:
return 'NaN'
if length == 0:
return '0'
getcontext().prec = 200
value = Decimal(0)
scale = Decimal(1)
for i in range(length):
digit = sbData.GetUnsignedInt16(sbError, 4 + 2 * i)
if sbError.Fail():
raise Exception('unable to read memory: ' + sbError.GetCString())
value += scale * Decimal(digit)
scale *= 65536
value = value.scaleb(exponent)
if isNegative:
value = -value
return str(value)
def __lldb_init_module(debugger, internal_dict):
print('registering Decimal type summaries')
debugger.HandleCommand('type summary add Foundation.Decimal -F "' + __name__ + '.stringForDecimal"')
debugger.HandleCommand('type summary add NSDecimal -F "' + __name__ + '.stringForDecimal"')
This looks like an lldb bug. Please file a bug about this against lldb with http://bugs.swift.org.
For background: there is some magic going on behind your back in the Dictionary case. I can't show this in the REPL, but if you have a [String : Decimal] array as a local variable in some real code and do:
(lldb) frame variable --raw dec_array
(Swift.Dictionary<Swift.String, Foundation.Decimal>) dec_array = {
_variantBuffer = native {
native = {
_storage = 0x0000000100d05780 {
Swift._SwiftNativeNSDictionary = {}
bucketCount = {
_value = 2
}
count = {
_value = 1
}
initializedEntries = {
values = {
_rawValue = 0x0000000100d057d0
}
bitCount = {
_value = 2
}
}
keys = {
_rawValue = 0x0000000100d057d8
}
values = {
_rawValue = 0x0000000100d057f8
}
seed = {
0 = {
_value = -5794706384231184310
}
1 = {
_value = 8361200869849021207
}
}
}
}
cocoa = {
cocoaDictionary = 0x00000001000021b0
}
}
}
A swift Dictionary doesn't actually contain the dictionary elements anywhere obvious, and certainly not as ivars. So lldb has a "Synthetic child provider" for Swift Dictionaries that makes up SBValues for the keys and values of the Dictionary, and it is one of those synthetic children that your formatter is being handed.
That's also why the load address is -1. That really means "this is a synthetic thing whose data lldb is directly managing, not a thing at an address somewhere in your program." The same thing is true of REPL results, they are more a fiction lldb maintains. But if you looked at a local variable of type Decimal, you would see a valid load address, because it is a thing that lives somewhere in memory.
Anyway, so apparently the Synthetic children Decimal objects we are making up to represent the values of the dictionary don't set the start of the data correctly. Interestingly enough, if you make a [Decimal : String] dictionary, the key field's SBData is correct, and your formatter works. It's just the values that aren't right.
I tried the same thing with Dictionaries that have Strings as values, and the SBData looks correct there. So there's something funny about Decimal. Anyway, thanks for pursuing this, and please do file a bug.

Is each of these one single UTF-8 character?

I want to be able to insert these characters into my clipboard programmatically. Is each of them one single UTF-8 character? If not, what encoding are they in?
I was looking though UTF-8 character table http://www.utf8-chartable.de/unicode-utf8-table.pl under latin letters but couldn't find them.
Ấ
Ầ
Ẩ
Ẫ
Ậ
Ứ
Ừ
Ử
Ữ
Ự
Ỡ
Ợ
Ở
Ề
Ể
Ễ
The character table you linked to in your question covers only the codepoints in Unicode's Basic Latin (U+0000..U+007F) and Latin-1 Supplement (U+0080..U+00FF) blocks. Each of the characters you have shown are codepoints in Unicode's Latin Extended Additional block (U+1E00..U+1EFF). When encoded in UTF-8, these characters take up 3 bytes each, as follows:
Ấ = U+1EA4 = E1 BA A4
Ầ = U+1EA6 = E1 BA A6
Ẩ = u+1EA8 = E1 BA A8
Ẫ = U+1EAA = E1 BA AA
Ậ = U+1EAC = E1 BA AC
Ứ = U+1EE8 = E1 BB A8
Ừ = U+1EEA = E1 BB AA
Ử = U+1EEC = E1 BB AC
Ữ = U+1EEE = E1 BB AE
Ự = U+1EF0 = E1 BB B0
Ỡ = U+1EE0 = E1 BB A0
Ợ = U+1EE2 = E1 BB A2
Ở = U+1EDE = E1 BB 9E
Ề = U+1EC0 = E1 BB 80
Ể = U+1EC2 = E1 BB 82
Ễ = U+1EC4 = E1 BB 84
Depending on your platform, you may or may not be able to store UTF-8 on the clipboard. For instance, on Windows, you can store text only as ANSI or UTF-16 (unless you create a custom clipboard format to hold UTF-8).

Powershell month name to number

I have this snippet of code that converts a registry value to a date string (originally hex value 2f 04 1e 00 00 00 00 00):
ElseIf (($sepmastersvc)) {
$sepmasterst = [bool]$sepmaster
$sepStatus = $sepmastersvc.status
$SEPVscan = (get-itemproperty "HKLM:SOFTWARE\Wow6432Node\Symantec\Symantec Endpoint Protection\AV") 2> $null
If (!($SEPVscan)) {
$SEPVscanStatus = [bool]$SEPVscan
$SEPDatVer = "N/A"
}
Else {
$SEPVscanStatus = [bool]$SEPVscan
$SEPDatVerY = [string]($SEPVscan.PatternFileDate[0] + 1970)
$SEPDatVerM = ($DateTimeFormat.MonthNames[$SEPVscan.PatternFileDate[1]])
$SEPDatD = [string]$SEPVscan.PatternFileDate[2]
$SEPDatVer = $SEPDatVerY + $SEPDatVerM + $SEPDatD
}
}
I need to get the month number instead of name.
I've found examples of converting a month number to name but can't get it working the other way around.
You can use Get-Date and specify the format. "MM" will retrieve the month in 2 digit number.
get-date -format "MM"
Here is a list of possible formats: https://technet.microsoft.com/en-us/library/ee692801.aspx
I'm not sure what format your date is, but from what I can see, you could try
Get-Date -Date "$SEPDatVerM $SEPDatD $SEPDatVerY" -format "yyyy MM dd"
and that should give you a date formatted as this: for example "2015 03 21"

how can I import multiple csv files with selected columns using textscan?

I have a large number of csv files to be processed. I only want the selected columns in each file and then load all the files from a certain folder and then output as one combined file. Here are my codes running with errors.... Could anyone help me to solve this problem?
data_directory = 'C:\Users\...\data';
numfiles = 17;
for n = 1:numfiles
filepath = [data_directory,'data_', num2str(n),'_output.csv'];
fid = fopen (filepath, 'rt');
wanted_columns= [2 3 4 5 10 11 12 13 14 15 16 17 35 36 41 42 44 45 59 61];
format = [];
columns = 109;
for i = 1 : columns;
if any (i == wanted_columns)
format = [format '%s'];
else
format = [format '%*s'];
end
end
data = textscan(fid, format, 'Delimiter',',','HeaderLines',1);
fclose(fid);
end
I think you should check whether the file is opened correctly. The error message seems to indicate that this is not the case. If it is not, check if the filepath is correct.
fid = fopen (filepath, 'rt');
if fid == -1
error('Failed to open file');
end
If the error is thrown here, you know that there was a problem with 'fopen'.
Ofcourse I don't know which files are on your computer, but I assume the '...' in the filename is not in your actual matlab file, only in your question on SO.
But could it be that you repeat the word 'data', while the actual filename only contains 'data' once? You code now will result in filenames like ''C:\Users\...\datadata_1_output.csv'. Maybe 'data' should be removed in data_directory or in filepath = ...?
Here is another way how you can setup the format string in a vectorized manner:
fcell = repmat({'%*s '},1,n_columns);
fcell(wanted_columns) = {'%s '};
formatstr = [fcell{:}];
Notice format is a build-in function in MATLAB, and it's better not to be used for variable name.