LALSimulation  5.4.0.1-fe68b98
LALSimUnicorn.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include <gsl/gsl_rng.h>
7 
8 #include <lal/LALStdlib.h>
9 #include <lal/LALConstants.h>
10 #include <lal/AVFactories.h>
11 #include <lal/LALSimBurst.h>
12 
13 /* this is the xpm image of the unicorn! */
14 #define char const char /* to silence compiler warnings ... */
15 #include "unicorn.xpm"
16 #undef char
17 
18 /* RGB to luminance */
19 static double RGB2Y(double R, double G, double B)
20 {
21  double Y;
22  Y = 0.2126*R + 0.7152*G + 0.0722*B;
23  return Y;
24 }
25 
26 /* convert radix 256 string to unsigned long */
27 static unsigned long radix256toul(const char *s, size_t n)
28 {
29  unsigned long ul = 0;
30  memcpy(&ul, s, n < sizeof(ul) ? n : sizeof(ul));
31  return ul;
32 }
33 
34 /* converts a RGB color string of the form #xxxxxx to a luminance value */
35 static double strtolum(const char *s)
36 {
37  int R, G, B, max;
38  int width;
39  char fmt[64];
40  if (s[0] != '#') { /* not a rgb color! */
41  return -1.0;
42  }
43  width = strlen(s + 1);
44  width /= 3;
45  snprintf(fmt, sizeof(fmt), "#%%%dx%%%dx%%%dx", width, width, width);
46  sscanf(s, fmt, &R, &G, &B);
47  for (max = 16; width > 1; --width)
48  max *= 16;
49  return RGB2Y((double)R/(double)max, (double)G/(double)max, (double)B/(double)max);
50 }
51 
52 /* routine to parse a xmp file */
53 static REAL8Array *xpmtoarr(const char *xpm[])
54 {
55  REAL8Array *arr; /* the image stored as an array of luminance values */
56  double *Y; /* the luminance values of the tagged colors */
57  size_t nY;
58  int cols, rows, colors, chars_per_pixel;
59  int color, row;
60  int c;
61 
62  /* parse first line of xpm */
63  sscanf(xpm[0], "%d %d %d %d", &cols, &rows, &colors, &chars_per_pixel);
64  if (cols < 1 || rows < 1 || colors < 1 || chars_per_pixel < 1)
65  return NULL;
66 
67  /* allocate memory for lookup table of color luminance values */
68  for (c = 1, nY = 256; c < chars_per_pixel; ++c)
69  nY *= 256;
70  Y = LALMalloc(nY * sizeof(*Y));
71  if (!Y)
72  return NULL;
73 
74  /* parse lines of xpm to get color luminance values */
75  for (color = 0; color < colors; ++color) {
76  const char *s = xpm[1 + color];
77  size_t i;
78  i = radix256toul(s, chars_per_pixel);
79  s = strrchr(s, '#');
80  Y[i] = strtolum(s);
81  if (Y[i] < 0.0 || Y[i] > 1.0) {
82  /* an error occurred parsing this string */
83  LALFree(Y);
84  return NULL;
85  }
86  }
87 
88  /* scan the image and store luminance values in the array */
89  arr = XLALCreateREAL8ArrayL(2, rows, cols);
90  if (!arr) {
91  LALFree(Y);
92  return NULL;
93  }
94  for (row = 0; row < rows; ++row) {
95  const char *s = xpm[1 + colors + row];
96  int col;
97  for (col = 0; col < cols; ++col) {
98  size_t offset = row * cols + col;
99  size_t i;
100  i = radix256toul(s, chars_per_pixel);
101  arr->data[offset] = Y[i];
102  s += chars_per_pixel;
103  }
104  }
105 
106  LALFree(Y);
107  return arr;
108 }
109 
110 #if 0 /* for debugging purposes ... */
111 static void arr2asc(REAL8Array *arr)
112 {
113  size_t row, rows, col, cols;
114  rows = arr->dimLength->data[0];
115  cols = arr->dimLength->data[1];
116  for (row = 0; row < rows; ++row) {
117  for (col = 0; col < cols; ++col) {
118  int offset = row * cols + col;
119  char c;
120  if (arr->data[offset] < 0.3)
121  c = '.';
122  else if (arr->data[offset] < 0.6)
123  c = 'o';
124  else
125  c = 'O';
126  printf("%c", c);
127  }
128  printf("\n");
129  }
130  return;
131 }
132 #endif
133 
134 /**
135  * Generates a time-frequency unicorn signal.
136  *
137  * \warning Unicorns are rare and are hard to catch.
138  */
140  REAL8TimeSeries **hplus, /**< plus-polarization waveform [returned] */
141  REAL8TimeSeries **hcross, /**< cross-polarization waveform [returned] */
142  double f_min, /**< minimum frequency of the unicorn (Hz) */
143  double f_max, /**< maximum frequency of the unicorn (Hz) */
144  double V, /**< time-frequency volume of image pixels */
145  double hrss, /**< root-sum-squared value of the waveform (s) */
146  double deltaT, /**< sampleing interval (s) */
147  gsl_rng *rng /**< random number generator */
148 )
149 {
150  REAL8Array *arr;
151  size_t rows;
152  double dt, df, fstart;
153 
154  /* check sanity of input parameters */
155  XLAL_CHECK(V >= LAL_2_PI, XLAL_EINVAL, "Time-frequency volume must be greater than 2/pi");
156  XLAL_CHECK(f_max > f_min, XLAL_EINVAL, "Maximum frequency must be greater than minimum frequency");
157  XLAL_CHECK(f_max <= 0.5 / deltaT , XLAL_EINVAL, "Maximum frequency must be less than Nyquist frequency");
158 
159  /* create image array from xpm */
160  arr = xpmtoarr(unicorn);
161  if (!arr)
162  XLAL_ERROR(XLAL_EDATA, "Could not parse .xpm image file");
163 
164  /* generate waveform from image */
165  rows = arr->dimLength->data[0];
166  df = (f_max - f_min) / rows;
167  dt = V / df;
168  fstart = f_min + 0.5 * df;
169  if (XLALSimBurstImg(hplus, hcross, arr, dt, df, fstart, hrss, deltaT, rng) < 0)
172 
173  return 0;
174 }
#define LALMalloc(n)
#define LALFree(p)
#define c
#define G
static REAL8Array * xpmtoarr(const char *xpm[])
Definition: LALSimUnicorn.c:53
static unsigned long radix256toul(const char *s, size_t n)
Definition: LALSimUnicorn.c:27
static double strtolum(const char *s)
Definition: LALSimUnicorn.c:35
static double RGB2Y(double R, double G, double B)
Definition: LALSimUnicorn.c:19
int s
Definition: bh_qnmode.c:137
double dt
Definition: bh_ringdown.c:113
double i
Definition: bh_ringdown.c:118
const double B
REAL8Array * XLALCreateREAL8ArrayL(UINT4,...)
void XLALDestroyREAL8Array(REAL8Array *)
#define LAL_2_PI
int XLALSimUnicorn(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, double f_min, double f_max, double V, double hrss, double deltaT, gsl_rng *rng)
Generates a time-frequency unicorn signal.
int XLALSimBurstImg(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8Array *image, double dt, double df, double fstart, double hrss, double deltaT, gsl_rng *rng)
Generates a burst injection with a time-frequency structure specified in an image array.
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
XLAL_EDATA
XLAL_EFUNC
XLAL_EINVAL
UINT4Vector * dimLength
REAL8 * data
UINT4 * data
double V
Definition: unicorn.c:25
double hrss
Definition: unicorn.c:21
double f_min
Definition: unicorn.c:22
double deltaT
Definition: unicorn.c:24
double f_max
Definition: unicorn.c:23