Skip to content

Commit

Permalink
Merge pull request #87 from JesseMckinzie/bug_fixes_1_10_24
Browse files Browse the repository at this point in the history
bugfix: escaped parenthesis, space in directory name, and capturing directories with special characters
  • Loading branch information
sameeul authored Jan 11, 2025
2 parents d7774d7 + e09b67e commit ac9cc36
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 10 deletions.
17 changes: 9 additions & 8 deletions src/filepattern/cpp/internal/filepattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ FilePatternObject::FilePatternObject(const string& path, const string& file_patt
this->getPathFromPattern(path); // set path and file_pattern

try {
this->recursive_iterator_ = fs::recursive_directory_iterator(this->getPath());
this->recursive_iterator_ = fs::recursive_directory_iterator(fs::path(this->getPath()));
this->recursive_ = true;
this->setJustPath(true);
} catch (const std::runtime_error& e) {
Expand All @@ -24,7 +24,8 @@ FilePatternObject::FilePatternObject(const string& path, const string& file_patt
} else {

this->recursive_ = recursive; // Iterate over subdirectories

this->setCaptureDirectoryNames(false);

// check if filepattern contains directory capturing
if (s::isPath(file_pattern)) {
this->setCaptureDirectoryNames(true);
Expand All @@ -37,12 +38,12 @@ FilePatternObject::FilePatternObject(const string& path, const string& file_patt

this->setJustPath(false);
this->setPath(path); // store path to target directory

try {
if(recursive){
this->recursive_iterator_ = fs::recursive_directory_iterator(this->getPath());
if(this->recursive_){
this->recursive_iterator_ = fs::recursive_directory_iterator(fs::path(this->getPath()));
} else{
this->iterator_ = fs::directory_iterator(this->getPath()); // store iterator for target directory
this->iterator_ = fs::directory_iterator(fs::path(this->getPath())); // store iterator for target directory
}
} catch (const std::runtime_error& e) {
string error = "No directory found. Invalid path \"" + path + "\".";
Expand Down Expand Up @@ -115,9 +116,9 @@ void FilePatternObject::matchFilesMultDir(){
} else {
file = s::getBaseName(file_path);
}

if(regex_match(file, sm, pattern_regex)){

if(this->getJustPath() || this->captureDirectoryNames()) {
tup = getVariableMap(file_path, sm);
} else {
Expand Down
5 changes: 3 additions & 2 deletions src/filepattern/cpp/util/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ namespace s {
const std::unordered_set<char> escape_chars = {'*', '?', '^', '$', '(', ')', '[', ']', '|'};

for (auto i = 0; i < str.size()-1; ++i) {
if (str[i] == '\\' &&
std::find(std::begin(escape_chars), std::end(escape_chars), str[i+1]) == std::end(escape_chars)
if ((str[i] == '\\' &&
std::find(std::begin(escape_chars), std::end(escape_chars), str[i+1]) == std::end(escape_chars)) ||
str[i] == '/'
) {
return true; // Contains a slash that is not proceeded by a character being escaped
}
Expand Down
49 changes: 49 additions & 0 deletions tests/test_filepattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ class TestFilePattern():
test_generate_filepattern_data.generate_channel_data()
test_generate_filepattern_data.generate_sorted_data()
test_generate_filepattern_data.generate_bracket_data()
test_generate_filepattern_data.generate_channel_data_sc()
test_generate_filepattern_data.generate_channel_data_spaces()

def test_file_pattern(self):

Expand Down Expand Up @@ -579,7 +581,54 @@ def test_recursive_directory_regex_fp(self):
assert fp_data.test_recursive_directory_fp[i][0]["directory"] == result[i][0]["directory"]
assert str(os.path.basename(fp_data.test_recursive_directory_fp[i][1][0])) == os.path.basename(result[i][1][0])

def test_recursive_directory_regex_special_character_fp(self):

path = self.root_directory + '/test_data/recursive_data_sc'

filepattern = '/(?P<directory>.*)/img_r{r:ddd}_c{c:ddd}.tif'

files = fp.FilePattern(path, filepattern, recursive=True)

result = []

for file in files():
result.append(file)

# test that same number of files are returned
assert len(result) == len(fp_data.test_recursive_directory_fp)

# test that each variable and path are equal for each file in list
for i in range(len(fp_data.test_recursive_directory_fp)):
print(result[i])
assert fp_data.test_recursive_directory_fp[i][0]["r"] == result[i][0]["r"]
assert fp_data.test_recursive_directory_fp[i][0]["c"] == result[i][0]["c"]
assert fp_data.test_recursive_directory_fp[i][0]["directory"] + '_TEST' == result[i][0]["directory"]
assert str(os.path.basename(fp_data.test_recursive_directory_fp[i][1][0])) == os.path.basename(result[i][1][0])

def test_recursive_directory_spaces_fp(self):

path = self.root_directory + '/test_data/recursive_data_spaces/'

filepattern = 'img_r{r:ddd}_c{c:ddd}.tif'

files = fp.FilePattern(path, filepattern, recursive=True)

result = []

for file in files():
result.append(file)

print(result)

# test that same number of files are returned
assert len(result) == len(fp_data.test_recursive_space)

# test that each variable and path are equal for each file in list
for i in range(len(fp_data.test_recursive_space)):
print(result[i])
assert fp_data.test_recursive_space[i][0]["r"] == result[i][0]["r"]
assert fp_data.test_recursive_space[i][0]["c"] == result[i][0]["c"]
assert str(os.path.basename(fp_data.test_recursive_space[i][1][0])) == os.path.basename(result[i][1][0])

def test_recursive_multi_directory_regex_fp(self):

Expand Down
39 changes: 39 additions & 0 deletions tests/test_filepattern_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,3 +647,42 @@
({'c': 1, 'directory': 'TXREAD', 'r': 2}, ['/Users/jmckinzie/Documents/GitHub/filepattern-1/tests/test_data/recursive_data/TXREAD/img_r002_c001.tif']),
({'c': 2, 'directory': 'TXREAD', 'r': 2}, ['/Users/jmckinzie/Documents/GitHub/filepattern-1/tests/test_data/recursive_data/TXREAD/img_r002_c002.tif']),
]

test_recursive_space = [
(
{'c': 0, 'r': 0},
['img_r000_c000.tif', 'img_r000_c000.tif', 'img_r000_c000.tif']
),
(
{'c': 1, 'r': 0},
['img_r000_c001.tif', 'img_r000_c001.tif', 'img_r000_c001.tif']
),
(
{'c': 2, 'r': 0},
['img_r000_c002.tif', 'img_r000_c002.tif', 'img_r000_c002.tif']
),
(
{'c': 0, 'r': 1},
['img_r001_c000.tif', 'img_r001_c000.tif', 'img_r001_c000.tif']
),
(
{'c': 1, 'r': 1},
['img_r001_c001.tif', 'img_r001_c001.tif', 'img_r001_c001.tif']
),
(
{'c': 2, 'r': 1},
['img_r001_c002.tif', 'img_r001_c002.tif', 'img_r001_c002.tif']
),
(
{'c': 0, 'r': 2},
['img_r002_c000.tif', 'img_r002_c000.tif', 'img_r002_c000.tif']
),
(
{'c': 1, 'r': 2},
['img_r002_c001.tif', 'img_r002_c001.tif', 'img_r002_c001.tif']
),
(
{'c': 2, 'r': 2},
['img_r002_c002.tif', 'img_r002_c002.tif', 'img_r002_c002.tif']
)
]
108 changes: 108 additions & 0 deletions tests/test_generate_filepattern_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,112 @@ def generate_channel_data():

print("Files generated.")

def generate_channel_data_sc():

MAX = 3

directory = 'test_data'
root_directory = os.path.dirname(os.path.realpath(__file__))
path = os.path.join(root_directory, directory)
data_path = path + '/data'
recursive_path = path + '/recursive_data_sc'

try:
os.mkdir(path)
os.mkdir(data_path)
os.mkdir(recursive_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

try:
os.mkdir(data_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

try:
os.mkdir(recursive_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

channels = ['DAPI_TEST', 'TXREAD_TEST', 'GFP_TEST']

for channel in channels:
current_path = recursive_path + '/' + channel
try:
os.mkdir(current_path)
except FileExistsError:
print("Channel directory already exists")

for i in range(0, MAX):

str_i = str(i).zfill(3)

for j in range(0, MAX):

str_j = str(j).zfill(3)

recursive_name = 'img_r{}_c{}.tif'.format(str_i, str_j)
f = open(current_path + '/' + recursive_name, 'w+')
f.close()

print("Files generated.")

def generate_channel_data_spaces():

MAX = 3

directory = 'test_data'
root_directory = os.path.dirname(os.path.realpath(__file__))
path = os.path.join(root_directory, directory)
data_path = path + '/data'
recursive_path = path + '/recursive_data_spaces'

try:
os.mkdir(path)
os.mkdir(data_path)
os.mkdir(recursive_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

try:
os.mkdir(data_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

try:
os.mkdir(recursive_path)
print('Data directory created at ' + path)
except FileExistsError:
print("Data directory already exists")

channels = ['DAPI TEST', 'TXREAD TEST', 'GFP TEST']

for channel in channels:
current_path = recursive_path + '/' + channel
try:
os.mkdir(current_path)
except FileExistsError:
print("Channel directory already exists")

for i in range(0, MAX):

str_i = str(i).zfill(3)

for j in range(0, MAX):

str_j = str(j).zfill(3)

recursive_name = 'img_r{}_c{}.tif'.format(str_i, str_j)
f = open(current_path + '/' + recursive_name, 'w+')
f.close()

print("Files generated.")

def generate_sorted_data():
MAX = 30
length = 0
Expand Down Expand Up @@ -171,6 +277,8 @@ def generate_bracket_data():
generate_sorted_data()
generate_text_data()
generate_bracket_data()
generate_channel_data_sc
generate_channel_data_spaces


MAX = 3
Expand Down

0 comments on commit ac9cc36

Please sign in to comment.