Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ias2regdef() #46

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4f4cb12
correct inst/extdata/story0*-regdef.txt
monicaycli Sep 28, 2017
8e98bcc
add ias2regdef() & roxygen block template
monicaycli Oct 4, 2017
fe81e37
ias2regdef(): add read from ias file code and documentation
monicaycli Oct 4, 2017
10093a0
ias2regdef(): add parameters and defult values
monicaycli Oct 4, 2017
3eb86f2
ias2regdef(): add yaml block based on reg2regdef
monicaycli Oct 4, 2017
32f03df
ias2regdef(): add comment for read in ias file
monicaycli Oct 5, 2017
b9c2de5
ias2regdef(): add reg.sep parameter
monicaycli Oct 5, 2017
c34f9a1
ias2regdef(): add regdef block based on reg2regdef
monicaycli Oct 5, 2017
dfb9f8d
ias2regdef(): loop over multi-lines of ias
monicaycli Oct 5, 2017
b78cf46
ias2regdef(): specify no quotes around text in ias files
monicaycli Oct 5, 2017
5e0852d
correct inst/extdata/story0*-regdef.txt
monicaycli Oct 5, 2017
999ddfa
ias2regdef(): calc chrW based on 1st line of text
monicaycli Oct 5, 2017
9d41370
ias2regdef(): replace user-spec reg.sep with "\t"
monicaycli Oct 5, 2017
b573f0f
ias2regdef(): change parameter ias.file to fname
monicaycli Oct 5, 2017
29718e6
ias2regdef(): chrH is half of the diff b/t y1 & y2
monicaycli Oct 5, 2017
5ee8b5c
ias2regdef(): add argument baseline.offset
monicaycli Oct 5, 2017
5c1be90
ias2regdef(): min diff b/t region widths as chrW
monicaycli Oct 5, 2017
6774c07
ias2regdef(): add option for writing regdef file
monicaycli Oct 12, 2017
21ba126
ias2regdef(): error msg if area type != RECTANGLE
monicaycli Oct 12, 2017
d1989de
ias2redgef(): add warnings re interest area order
monicaycli Oct 12, 2017
96b3cc9
fix typo for regdef2ias documentation
monicaycli Oct 19, 2017
1b1ff6c
add/update ias2regdef() documentation
monicaycli Oct 19, 2017
0f6b862
ias2regdef(): move arg check for write.regdef to top
monicaycli Oct 19, 2017
4339b49
ias2regdef(): fix regex for replacing file name
monicaycli Nov 2, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export(getMargins)
export(getRegion)
export(get_start_pts)
export(get_xybounds)
export(ias2regdef)
export(inked)
export(makeReport)
export(mark_oob)
Expand Down
182 changes: 181 additions & 1 deletion R/textRegions.R
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ reg2regdef <- function(reg, scrnW=NA, scrnH=NA,
##' text displayed on that line. The second element is a regioning
##' string made up of square brackets ("[", "]"), and pipe ("|")
##' characters. An opening bracket ("[") indicates the start of a
##' line and a closing bracket ("]) indicates the end of a line.
##' line and a closing bracket ("]") indicates the end of a line.
##' Pipes ("|") indicate region boundaries within a line. By
##' default, the region definition file will specify that each
##' text line be exhaustively divided into space delimited regions
Expand Down Expand Up @@ -328,3 +328,183 @@ regdef2ias <- function(fname) {
}
ias
}


##' @title Convert SR Research IAS (Interest Area Set) file to region
##' definition file.
##' @description Convert SR Rsearch IAS (Interest Area Set) file
##' (*.ias) to a region definition file (*_regdef.txt). The latter
##' is suitable for hand editing and can be used to generate
##' alternative region specifications (e.g., multi word regions) for
##' text stimuli.
##'
##' @param fname A string containing the name of a SR Research IAS
##' file ("*.ias"). Columns in file from left to right must be:
##' Interest Area Type (Rectangular), Region Number, x1 (left
##' boundary), y1 (top boundary), x2 (right boundary), y2 (bottom
##' boundary), Region Label.
##' @param write.regdef A boolean value of whether or not a converted
##' region definition file will be written. Default value is
##' \code{TRUE}.
##' @param reg.sep A string of characters that denotes the region
##' separator in the region labels. Default value is \code{NA},
##' which indicates that region boundary is not specified within the
##' region labels, and region labels will be catenated with
##' \code{"\t"} in between to determine the locations of the region
##' boundaries. If \code{reg.sep} is specified by the user, the
##' \code{reg.sep} string will be replaced by \code{"\t"} to
##' determine the locations of the region boundaries.
##' @param baseline.offset Number of pixels of which the baseline of
##' each line is above from y2. Default value is \code{0}.
##'
##' @param scrnW Screen width in pixels (integer).
##' @param scrnH Screen height in pixels (integer).
##' @param fnt.name Font name used for stimulus text.
##' @param fnt.size Nominal font size in points for text display.
##' @param chrW Letter width in pixels, assuming a monospace font is
##' used.
##' @param chrH Nominal letter height in pixels.
##' @param ln.space Line spacing in pixels for multi line texts.
##' @param baseline Baseline positions for each line of text. Measured
##' in pixels from the top of the screen.
##' @param mrgn.top Top margin of the screen in pixels.
##' @param mrgn.left Left margin of the screen in pixels.
##' @param mrgn.bottom Bottom margin of the screen in pixels.
##' @param mrgn.right Right margin of the screen in pixels.
##' @param rgn.maxH Extent of regions of interest above baseline in
##' pixels.
##' @param rgn.minH Extent of regions of interest below baseline in
##' pixels.
##' @param rgn.padL Expand leftmost region on each line leftward by
##' this amount in pixels.
##' @param rgn.padR Expand rightmost region on each line rightward by
##' this amount in pixels.
##'
##' @details If not specified, \code{baseline}, \code{chrH} and
##' \code{chrW} will be calculated based on \code{x1}, \code{x2},
##' \code{y1}, and \code{y2} in the .ias file such that:
##' \itemize{
##' \item{\code{baseline = y2 - baseline.offset} for each line of text}
##' \item{\code{chrH = (y1 - y2)/2} for each line of text}
##' \item{\code{chrW} is the smallest differece between region
##' widths (i.e., \code{x2 - x1} of each region) among all regions.
##' (Note that it is assumed the font of the stimulus text is
##' monospace, and the estimation for \code{chrW} with proportional
##' fonts could be very off.)}
##' }
##'
##' Region labels (the last column in the .ias file) should be the
##' content of the actual stimulus for each region, especially in
##' terms of the number of characters or items within each region,
##' in order to generate optimal regdef files. This way, when
##' converting regdef to other formats, the region widths in the
##' regioning string can be directly converted into the actual
##' region widths in the stimulus. For example, if the stimuli are
##' color patches instead of text (like in Rapid Automatized
##' Naming), it may be ideal to use a single letter to stand for
##' each color as the region label, instead of using the whole name
##' of a color.
##'
##' @return A vector of strings containing the region definition. The
##' vector includes a yaml block with values for each of the
##' function parameters except for \code{fname},
##' \code{write.regdef}, \code{reg.sep}, and \code{baseline.offset}.
##' In addition to the yaml block, the vector will include a pair of
##' lines for each line of text in the stimulus. The first element
##' of each pair is the text displayed on that line. The second
##' element is a regioning string made up of square brackets ("[",
##' "]"), and pipe ("|") characters. An opening bracket ("[")
##' indicates the start of a line and a closing bracket ("]")
##' indicates the end of a line. Pipes ("|") indicate region
##' boundaries within a line.
##'
##' By default, the output vector is also written to a region
##' definition file (*_regdef.txt) using the file name of the input
##' .ias file. The region definition file can be hand edited to add
##' or correct information in the yaml block, or to re-specify
##' region placements.
##'
##' @author Dave Braze \email{davebraze@@gmail.com}
##' @author Monica Li \email{monica.yc.li@@gmail.com}
##' @export

ias2regdef <- function(fname, write.regdef=TRUE, reg.sep=NA, baseline.offset=0,
scrnW=NA, scrnH=NA,
fnt.name=NA, fnt.size=NA,
chrW=NA, chrH=NA,
ln.space=NA, baseline=NA,
mrgn.top=NA, mrgn.left=NA, mrgn.bottom=NA, mrgn.right=NA,
rgn.maxH=NA, rgn.minH=NA, rgn.padL=NA, rgn.padR=NA) {
##### read in ias file #####
ias <- read.table(fname, header = FALSE, sep = "\t", comment.char = "#", quote = "",
col.names = c("type","regnum","x1","y1","x2","y2","labs"))

# check input file and show error or warning messages
if (!all(ias$type=="RECTANGLE")) {stop("interest area type has to be RECTANGLE")}
if (!is.logical(write.regdef)) {stop("argument write.regdef must be a boolean")}
if (is.unsorted(ias$regnum)) {warning("interest area number is out of order")}
if (is.unsorted(ias$x1)|is.unsorted(ias$x2)) {
warning("interest area vertical boundaries (x1, x2) are out of order")
}
if (is.unsorted(ias$y1)|is.unsorted(ias$y2)) {
warning("interest area horizontal boundaries (y1, y2) are out of order")
}

##### build yaml block #####
if (is.na(baseline)) baseline <- unique(ias$y2)-baseline.offset
if (is.na(chrH)) chrH <- mean(ias$y2-ias$y1)/2
if (is.na(chrW)) chrW <- min(diff(sort(unique(ias$x2-ias$x1))))
scrn <- list(screen=list(width=as.integer(scrnW), height=as.integer(scrnH))) # likely defaults
fnt <- list(font=list(name=fnt.name, size=fnt.size)) # no default; not important to region definitions
chr <- list(character=list(width=as.integer(chrW), height=as.integer(chrH)))
lns <- list(lines=list(spacing=ln.space, baseline=as.integer(baseline)))
mrg <- list(margins=list(top=as.integer(mrgn.top), left=as.integer(mrgn.left),
bottom=as.integer(mrgn.bottom), right=as.integer(mrgn.right)))
rgns <- list(regions=list(maxH=as.integer(rgn.maxH), minH=as.integer(rgn.minH),
padL=as.integer(rgn.padL), padR=as.integer(rgn.padR)))
hdr <- c("---\n",
sapply(list(scrn, fnt, chr, lns, mrg, rgns), yaml::as.yaml),
"---\n")

##### build regdef block #####
# create an empty vector to store text and region definition lines
ln <- c()
# loop over each line of text
for (y in unique(ias$y2)){
# use y2 to identify text on the same line
ias_line <- subset(ias, y2==y)

# read in text and determine where the separators are
# replace separators with spaces
if (is.na(reg.sep)){
txt <- stringr::str_c(ias_line$labs, collapse="\t")
idx <- stringr::str_locate_all(txt, "\t")[[1]][,1]
txt <- gsub("\t", " ", txt)
} else {
txt <- stringr::str_c(ias_line$labs, collapse="")
txt <- gsub(reg.sep, "\t", txt)
idx <- stringr::str_locate_all(txt, "\t")[[1]][,1]
txt <- gsub("\t", " ", txt)
}

# create corresponding region marks for each line of text
regmarks <- rep(" ", stringr::str_length(txt))
regmarks[idx] <- "|"
regmarks[1] <- "["
regmarks[length(regmarks)] <- "]"
regmarks <- paste(regmarks, collapse="")

# stack text and region definition lines
ln <- c(paste0(ln, "\n", txt, "\n", regmarks, "\n"))
}

retval <- c(hdr, ln)

if (write.regdef==TRUE){
write(retval, gsub("[.]ias$", "_regdef.txt", fname))
invisible(retval)
} else {
return(retval)
}

}
60 changes: 34 additions & 26 deletions inst/extdata/story01-regdef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ lines:
- 208
- 269
- 332
- 393
- 454
- 515
- 576
- 637
- 698
- 397
- 458
- 519
- 580
- 641
- 702
- 767
- 828
margins:
top: 72 # distance from top of screen to top of 1st line of text in pixels
left: 215 # distance from left edge of screen to left edge of 1st character in line of text, in pixels.
Expand All @@ -37,32 +39,38 @@ regions:
Alex and Tim are lost. Alex's wife had recently passed away and he couldn't
[ | | | | | | | | | | | | | ]

find the motivation to live a normal life. Tim has been charged with embezzlement
[ | | | | | | | | | | | | | ]
find the motivation to live a normal life. Tim has been charged with
[ | | | | | | | | | | | | ]

and is going to prison soon. The thought of that terrified him. So they decided
[ | | | | | | | | | | | | | | ]
embezzlement and is going to prison soon. The thought of that terrified
[ | | | | | | | | | | | ]

to take a ride down the river rapids at Cataract Canyon. A river only goes one
[ | | | | | | | | | | | | | | | ]
him. So they decided to take a ride down the river rapids at Cataract Canyon.
[ | | | | | | | | | | | | | | ]

way. If you are lost, that is good. Alex has never rafted down this river before,
[ | | | | | | | | | | | | | | | ]
A river only goes one way. If you are lost, that is good. Alex has never
[| | | | | | | | | | | | | | | ]

but Tim has many times. Tim tells Alex that the rapids can be a dangerous place.
[ | | | | | | | | | | | | | | | ]
rafted down this river before, but Tim has many times. Tim tells Alex that
[ | | | | | | | | | | | | | ]

Boats can overturn and people fall in. Concerned, Alex asks a river guide for
[ | | | | | | | | | | | | | ]
the rapids can be a dangerous place. Boats can overturn and people fall
[ | | | | | | | | | | | | ]

advice. The guide tells him "sometimes things don't go as planned on the river,
[ | | | | | | | | | | | | | ]
in. Concerned, Alex asks a river guide for advice. The guide tells him
[ | | | | | | | | | | | | ]

and they turn for the worst. You might find yourself struggling, fighting against
[ | | | | | | | | | | | | ]
"sometimes things don't go as planned on the river, and they turn for the
[ | | | | | | | | | | | | | ]

the force of the river. When that happens in nature, it's best to surrender. You'd
[ | | | | | | | | | | | | | | ]
worst. You might find yourself struggling, fighting against the force of the
[ | | | | | | | | | | | ]

never hear a football coach tell you that, to surrender, but on the river its okay."
[ | | | | | | | | | | | | | | | ]
river. When that happens in nature, it's best to surrender. You'd never
[ | | | | | | | | | | | ]

hear a football coach tell you that, to surrender, but on the river its
[ | | | | | | | | | | | | | ]

okay."
[ ]
36 changes: 18 additions & 18 deletions inst/extdata/story02-regdef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,29 @@ regions:
padR: 0 # extent to pad last region on line to right of last character, in pixels.
---

The trial pack of Beauty-Forever pills made the couple feel
[ | | | | | | | | | ]
The trial pack of Beauty-Forever pills made the couple feel more attractive
[ | | | | | | | | | | | ]

more attractive than either had ever imagined possibly. Suddenly
[ | | | | | | | | ]
than either had ever imagined possibly. Suddenly their marriage was filled
[ | | | | | | | | | | ]

their marriage was filled with more laughter, more cuddling, more
[ | | | | | | | | | ]
with more laughter, more cuddling, more passionate sex more often.
[ | | | | | | | | | ]

passionate sex more often. Convinced, they became loyal customers.
[ | | | | | | | | ]
Convinced, they became loyal customers. One day, lying in bed, their
[ | | | | | | | | | | ]

One day, lying in bed, their seemingly perfect bodies naked and
[ | | | | | | | | | | ]
seemingly perfect bodies naked and spent together, the wife said, "Did you
[ | | | | | | | | | | | ]

spent together, the wife said, "Did you think I was beautiful before?"
[ | | | | | | | | | | | ]
think I was beautiful before? "The husband said, "Of course I did." She
[ | | | | | | | | | | | | ]

The husband said, "Of course I did." She replied, "Then let's stop taking
[ | | | | | | | | | | | | ]
replied, "Then let's stop taking the pills. Let's see each other as we
[ | | | | | | | | | | | | ]

the pills. Let's see each other as we really are." The husband looked
[ | | | | | | | | | | | | ]
really are." The husband looked at her, radiant beside him and said,
[ | | | | | | | | | | | ]

at her, radiant beside him and said, "Maybe tomorrow, dear. Maybe tomorrow."
[ | | | | | | | | | | | ]
"Maybe tomorrow, dear. Maybe tomorrow."
[ | | | | ]
Loading