dataset.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Vladimir Dergachev
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 #define _GNU_SOURCE
00021 #define _FILE_OFFSET_BITS 64
00022 #include <string.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <unistd.h>
00026 #include <errno.h>
00027 #include <alloca.h>
00028 #include <math.h>
00029 #include <sys/time.h>
00030 #include <time.h>
00031 
00032 #include <gsl/gsl_rng.h>
00033 #include <gsl/gsl_randist.h>
00034 #include <gsl/gsl_integration.h>
00035 
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <dirent.h>
00039 #include <fcntl.h>
00040 
00041 #include "dataset.h"
00042 #include "statistics.h"
00043 #include "cmdline.h"
00044 #include "intervals.h"
00045 #include "hookup.h"
00046 #include "grid.h"
00047 #include "rastermagic.h"
00048 #include "hookup.h"
00049 #include "util.h"
00050 #include "jobs.h"
00051 
00052 #include <lal/GeneratePulsarSignal.h>
00053 
00054 // typedef double REAL8;
00055 // typedef int INT4;
00056 // typedef float REAL4;
00057 
00058 extern FILE *LOG;
00059 extern struct gengetopt_args_info args_info;
00060 extern int first_bin;
00061 extern int nbins;
00062 
00063 extern int ntotal_polarizations;
00064 extern SKY_GRID *fine_grid;
00065 extern SKY_GRID *patch_grid;
00066 
00067 extern INT64 spindown_start;
00068 
00069 extern int fake_injection;
00070 extern double spindown;
00071 
00072 char s[20000];
00073 
00074 DATASET * datasets=NULL;
00075 int d_free=0;
00076 int d_size=0;
00077 
00078 extern int do_CutOff;
00079 
00080 int lock_file=-1;
00081 
00082 /* this is a busy wait.. as condor does not allow sleep() */
00083 static void spin_wait(int seconds)
00084 {
00085 time_t start_time, end_time;
00086 int i;
00087 time(&start_time);
00088 i=0;
00089 while(1) {
00090         i++;
00091         if(i>1000000) {
00092                 time(&end_time);
00093                 if(end_time>start_time+seconds)return;
00094                 i=0;
00095                 }
00096         }
00097 }
00098 
00099 /* we need the structure to be global as a workaround for a bug in condor libraries:
00100    this way the pointer is 32bit even on 64bit machines */
00101 
00102 static void acquire_lock(char *filename)
00103 {
00104 int i;
00105 struct flock fl;
00106 
00107 lock_file=open(filename, O_CREAT | O_RDWR, 0666);
00108 
00109 memset(&fl, 0, sizeof(fl));
00110 fl.l_type=F_WRLCK;
00111 fl.l_whence=SEEK_SET;
00112 fl.l_start=0;
00113 fl.l_len=1;
00114 errno=0;
00115 i=0;
00116 while((lock_file<0) || (direct_fcntl(lock_file, F_SETLK, &fl)<0)){
00117         if(lock_file<0) {
00118                 fprintf(stderr, "Could not open file \"%s\" for locking\n", filename);
00119                 }
00120         if(i>10) {
00121                 fprintf(stderr, "Waiting for lock: %s\n", strerror(errno));
00122                 i=0;
00123                 }
00124         if(lock_file>=0)close(lock_file);
00125         condor_safe_sleep(args_info.lock_retry_delay_arg);
00126         lock_file=open(filename, O_CREAT | O_RDWR, 0666);
00127         i++;
00128         }
00129 }
00130 
00131 static void release_lock(void)
00132 {
00133 if(lock_file>=0)close(lock_file);
00134 lock_file=-1;
00135 }
00136 
00137 typedef struct {
00138         float e[26];
00139         int bin;
00140 
00141         double a_plus;
00142         double a_cross;
00143         double cos_e;
00144         double sin_e;
00145 
00146         double segment_start;
00147 
00148         double ref_time;
00149 
00150         double freq;
00151         double spindown;
00152 
00153         double ra;
00154         double dec;
00155 
00156         double coherence_time;
00157 
00158         double extra_phase; /* phase accumulated from the start of the run */
00159         double phase_integration_factor;
00160 
00161         } SIGNAL_PARAMS;
00162 
00163 static void compute_signal(double *re, double *im, double *f, double t, SIGNAL_PARAMS *p)
00164 {
00165 float det_vel[3]={NAN, NAN, NAN};
00166 float f_plus, f_cross;
00167 double doppler, omega_t, c_omega_t, s_omega_t;
00168 double hann;
00169 
00170 get_detector_vel(round(t), det_vel);
00171 
00172 doppler=p->e[0]*det_vel[0]+p->e[1]*det_vel[1]+p->e[2]*det_vel[2];
00173 
00174 /*get_AM_response(round(t), p->dec, p->ra, 0.7853982, &f_plus, &f_cross);
00175 fprintf(stderr, "%d f_plus=%f f_cross=%f\n", (int)round(t), f_plus, f_cross);*/
00176 get_AM_response(round(t), p->dec, p->ra, 0.0, &f_plus, &f_cross);
00177 // fprintf(stderr, "%d f_plus=%f f_cross=%f\n", (int)round(t), f_plus, f_cross);
00178 
00179 *f=p->freq*(1.0+doppler)+p->spindown*(t-p->ref_time);
00180 
00181 //*f=p->freq*(1.0+doppler);
00182 
00183 omega_t=2.0*M_PI*(*f-p->bin/p->coherence_time)*(t-p->segment_start)+p->extra_phase;
00184 hann=0.5*(1.0-cos(2.0*M_PI*(t-p->segment_start)/p->coherence_time));
00185 
00186 c_omega_t=cos(omega_t);
00187 s_omega_t=sin(omega_t);
00188 
00189 /* 
00190         cos(a)*cos(-b)=0.5*(cos(a-b)+cos(a+b))
00191         sin(a)*cos(-b)=0.5*(sin(a-b)+sin(a+b))
00192         cos(a)*sin(-b)=0.5*(sin(a-b)-sin(a+b))
00193         sin(a)*sin(-b)=0.5*(cos(a-b)-cos(a+b))
00194 
00195         |f-w|<<1
00196         cos(ft)*exp(-iwt)~= 0.5*(cos((f-w)t)+i*sin((f-w)t))
00197         sin(ft)*exp(-iwt)~= 0.5*(sin((f-w)t)-i*cos((f-w)t))
00198 */
00199 
00200 // fprintf(stderr, "a_plus=%f a_cross=%f cos_e=%f sin_e=%f\n", p->a_plus, p->a_cross, p->cos_e, p->sin_e);
00201 
00202 /* Note: we do not have an extra factor of 0.5 because of normalization convention used, 
00203   there is an extra factor of 2.0 to compensate for Hann windowing */
00204 *re=hann*(f_plus*(p->a_plus*c_omega_t*p->cos_e-p->a_cross*s_omega_t*p->sin_e)+
00205         f_cross*(p->a_plus*c_omega_t*p->sin_e+p->a_cross*s_omega_t*p->cos_e));
00206 
00207 *im=hann*(f_plus*(p->a_plus*s_omega_t*p->cos_e+p->a_cross*c_omega_t*p->sin_e)+
00208         f_cross*(p->a_plus*s_omega_t*p->sin_e-p->a_cross*c_omega_t*p->cos_e));
00209 
00210 //fprintf(stderr, "response=%g a_plus=%g a_cross=%g \n", response, p->a_plus, p->a_cross);
00211 
00212 // fprintf(stderr, "f=%.4f (%.3f) re=%.2f im=%.2f omega_t=%.2f t=%.1f (%f) doppler=%g\n", (*f), (*f)*1800.0-p->bin*1.0, *re, *im, omega_t, t-p->ref_time, t, doppler);
00213 
00214 }
00215 
00216 static double signal_re(double t, void *params)
00217 {
00218 double re, im, f;
00219 compute_signal(&re, &im, &f, t, params);
00220 return(re);
00221 }
00222 
00223 static double signal_im(double t, void *params)
00224 {
00225 double re, im, f;
00226 compute_signal(&re, &im, &f, t, params);
00227 return(im);
00228 }
00229 
00230 static double signal_omega(double t, void *params)
00231 {
00232 SIGNAL_PARAMS *p=params;
00233 float det_vel[3];
00234 double doppler, omega;
00235 
00236 get_detector_vel(round(t), det_vel);
00237 
00238 doppler=p->e[0]*det_vel[0]+p->e[1]*det_vel[1]+p->e[2]*det_vel[2];
00239 omega=2.0*M_PI*p->freq*doppler-p->phase_integration_factor;
00240 
00241 return(omega);
00242 }
00243 
00244 static double compute_phase(gsl_integration_workspace *giw, int giw_size, double start_time, double end_time)
00245 {
00246 SIGNAL_PARAMS p;
00247 gsl_function F; 
00248 int err;
00249 double result, abserr;
00250 double T=end_time-start_time;
00251 
00252 if(!(fabs(T)>0))return 0.0;
00253 
00254 F.params=&p;
00255 p.bin=0;
00256 
00257 p.ra=args_info.fake_ra_arg;
00258 p.dec=args_info.fake_dec_arg;
00259 p.freq=args_info.fake_freq_arg;
00260 p.spindown=args_info.fake_spindown_arg;
00261 p.ref_time=args_info.fake_ref_time_arg;
00262 p.segment_start=0;
00263 p.coherence_time=0;
00264 
00265 p.cos_e=cos(2.0*(args_info.fake_psi_arg-args_info.fake_phi_arg));
00266 p.sin_e=sin(2.0*(args_info.fake_psi_arg-args_info.fake_phi_arg));
00267 
00268 precompute_am_constants(p.e, args_info.fake_ra_arg, args_info.fake_dec_arg);
00269 
00270 F.function=signal_omega;
00271 p.phase_integration_factor=0.0;
00272 
00273 while(1) {
00274         err=gsl_integration_qag(&F, start_time, end_time,
00275                 1e-6, 1e-5,
00276                 giw_size,
00277                 GSL_INTEG_GAUSS61,
00278                 giw,
00279                 &result,
00280                 &abserr
00281                 );
00282 
00283         if(fabs(result)>10) {
00284                 p.phase_integration_factor+=result/T;
00285                 continue;
00286                 }
00287 
00288         p.extra_phase=result+p.phase_integration_factor*T+
00289                 2*M_PI*(p.freq*T+0.5*p.spindown*T*T+p.spindown*(start_time-p.ref_time)*T);
00290 
00291 /*      if(err)fprintf(stderr, "phase %d result=%g (%g) pif=%g abserr=%g %s\n", segment, result, result/(d->gps[segment]-p.ref_time), p.phase_integration_factor, abserr,  gsl_strerror(err)); */
00292         break;
00293         }
00294 return(p.extra_phase);
00295 }
00296 
00297 static void test_inject_fake_signal(void)
00298 {
00299 SIGNAL_PARAMS p;
00300 double cos_i;
00301 double re, im, f, re2, im2, f2;
00302 int status=0;
00303 
00304 p.bin=0;
00305 
00306 p.ra=2.56;
00307 p.dec=1.43;
00308 p.freq=500.12;
00309 p.spindown=1.23e-9;
00310 p.ref_time=793154935;
00311 p.segment_start=793161245;
00312 p.coherence_time=1800.0;
00313 p.extra_phase=0;
00314 
00315 cos_i=cos(1.23);
00316 
00317 p.a_plus=(1+cos_i*cos_i)*0.5;
00318 p.a_cross=cos_i;
00319 
00320 p.cos_e=cos(2.0*(1.23));
00321 p.sin_e=sin(2.0*(1.23));
00322 precompute_am_constants(p.e, p.ra, p.dec);
00323 
00324 get_detector("LHO");
00325 
00326 compute_signal(&re, &im, &f, 793161250.0, &p);
00327 fprintf(stderr, "compute_signal_test1: %g %g %f\n", re, im, f);
00328 fprintf(LOG, "compute_signal_test1: %g %g %f\n", re, im, f);
00329 
00330 if(abs(re-9.59669e-06)>1e-11 ||
00331    abs(im-1.83957e-05)>1e-11 ||
00332    abs(f-500.101774)>1e-5) status|=1;
00333 
00334 p.cos_e=1.0;
00335 p.sin_e=0.0;
00336 
00337 compute_signal(&re, &im, &f, 793161250.0, &p);
00338 fprintf(stderr, "compute_signal_test2: %g %g %f\n", re, im, f);
00339 fprintf(LOG, "compute_signal_test2: %g %g %f\n", re, im, f);
00340 
00341 p.cos_e=1.0;
00342 p.sin_e=0.0;
00343 p.extra_phase=M_PI*0.5;
00344 
00345 compute_signal(&re2, &im2, &f2, 793161250.0, &p);
00346 fprintf(stderr, "compute_signal_test3: %g %g %f\n", re2, im2, f2);
00347 fprintf(LOG, "compute_signal_test3: %g %g %f\n", re2, im2, f2);
00348 
00349 if(abs(f2-f)>1e-5 ||
00350    abs(re-im2)>1e-11 ||
00351    abs(im+re2)>1e-11) status|=2;
00352 
00353 if(status) {
00354         fprintf(stderr, "compute_signal_test: failed %d\n", status);
00355         fprintf(LOG, "compute_signal_test: failed %d\n", status);
00356         exit(-1);
00357         }
00358 }
00359 
00360 static void inject_fake_signal(DATASET *d, int segment, double accumulated_phase)
00361 {
00362 double result, abserr;
00363 size_t neval;
00364 int err;
00365 int window=5, bin;
00366 int i;
00367 double re, im, f, cos_i;
00368 SIGNAL_PARAMS p;
00369 gsl_function F; 
00370 
00371 F.params=&p;
00372 p.bin=0;
00373 
00374 p.ra=args_info.fake_ra_arg;
00375 p.dec=args_info.fake_dec_arg;
00376 p.freq=args_info.fake_freq_arg;
00377 p.spindown=args_info.fake_spindown_arg;
00378 p.ref_time=args_info.fake_ref_time_arg;
00379 p.segment_start=d->gps[segment];
00380 p.coherence_time=d->coherence_time;
00381 
00382 //fprintf(stderr, "frequency=%f spindown=%g ra=%f dec=%f\n", p.freq, p.spindown, p.ra, p.dec);
00383 
00384 cos_i=cos(args_info.fake_iota_arg);
00385 
00386 p.a_plus=(1+cos_i*cos_i)*0.5;
00387 p.a_cross=cos_i;
00388 
00389 p.cos_e=cos(2.0*(args_info.fake_psi_arg-args_info.fake_phi_arg));
00390 p.sin_e=sin(2.0*(args_info.fake_psi_arg-args_info.fake_phi_arg));
00391 
00392 // fprintf(stderr, "a_plus=%f a_cross=%f cos_e=%f sin_e=%f\n", p.a_plus, p.a_cross, p.cos_e, p.sin_e);
00393 
00394 precompute_am_constants(p.e, args_info.fake_ra_arg, args_info.fake_dec_arg);
00395 compute_signal(&re, &im, &f, d->gps[segment]+(int)(d->coherence_time/2), &p);
00396 
00397 
00398 bin=round(f*1800.0-d->first_bin);
00399 if((bin+window>nbins) || (bin<window))fprintf(stderr, "Injected signal outside loaded band: bin=%d, segment=%d\n", bin, segment);
00400 if(bin+window>nbins)bin=nbins-window;
00401 if(bin<window)bin=window;
00402 
00403 p.extra_phase=accumulated_phase;
00404 
00405 
00406 for(i=bin-window; i<=bin+window; i++) {
00407         p.bin=i+d->first_bin;
00408 
00409         F.function=signal_re;
00410         err=gsl_integration_qng(&F, d->gps[segment], d->gps[segment]+d->coherence_time,
00411                 1, 1e-3,
00412                 &result, &abserr, &neval);
00413 /*      fprintf(stderr, "re %d %d result=%g abserr=%g %d %s\n", segment, i, result, abserr, neval, gsl_strerror(err)); */
00414         d->re[segment*d->nbins+i]+=args_info.fake_strain_arg*result*16384.0/args_info.strain_norm_factor_arg;
00415 
00416 
00417         F.function=signal_im;
00418         err=gsl_integration_qng(&F, d->gps[segment], d->gps[segment]+d->coherence_time,
00419                 1, 1e-3,
00420                 &result, &abserr, &neval);
00421 /*      fprintf(stderr, "im %d %d result=%g abserr=%g %d %s\n", segment, i, result, abserr, neval, gsl_strerror(err)); */
00422         d->im[segment*d->nbins+i]+=args_info.fake_strain_arg*result*16384.0/args_info.strain_norm_factor_arg;
00423         }
00424 
00425 }
00426 
00427 static void inject_fake_signal2(DATASET *d, int segment)
00428 {
00429 SFTandSignalParams sft_params;
00430 PulsarSignalParams pulsar_params;
00431 
00432 sft_params.resTrig=0;
00433 sft_params.Dterms=5;
00434 sft_params.nSamples=5;
00435 
00436 }
00437 
00438 static void init_dataset(DATASET *d)
00439 {
00440 int i;
00441 memset(d, 0, sizeof(*d));
00442 d->name="unknown";
00443 for(i=0;i<MAX_LOCKS;i++)
00444         d->lock_file[i]=NULL;
00445 d->validated=0;
00446 d->detector="unknown";
00447 d->gps_start=0;
00448 d->gps_stop=-1;
00449 
00450 d->coherence_time=1800.0;
00451 d->nbins=nbins;
00452 d->first_bin=first_bin;
00453 
00454 d->segment_list=NULL;
00455 d->veto_segment_list=NULL;
00456 d->no_duplicate_gps=1;
00457 
00458 d->size=1000;
00459 d->free=0;
00460 d->gps=do_alloc(d->size, sizeof(*d->gps));
00461 d->dc_factor=1.0;
00462 d->dc_factor_touched=0;
00463 d->dc_factor_blocked=0;
00464 d->re=do_alloc(d->size*d->nbins, sizeof(*d->re));
00465 d->im=do_alloc(d->size*d->nbins, sizeof(*d->im));
00466 d->sft_veto=NULL;
00467 d->veto_level=1e-2; /* this takes care of SFTs that have 1/100 weight... */
00468 d->veto_spike_level=1.7; /* this takes care of SFTs with spikes 50 times median level */
00469 
00470 d->weight=1.0;
00471 
00472 d->polarizations=NULL;
00473 d->polarizations=do_alloc(ntotal_polarizations, sizeof(*(d->polarizations)));
00474 memset(d->polarizations, 0, (ntotal_polarizations)*sizeof(*(d->polarizations)));
00475 }
00476 
00477 static void compute_detector_speed(DATASET *d)
00478 {
00479 int i;
00480 float det_vel_ra, det_vel_dec;
00481 double orbital_axis[3];
00482 float band_axis_ra, band_axis_dec;
00483 fprintf(stderr,"Computing detector speed for dataset %s\n", d->name);
00484 d->detector_velocity=do_alloc(3*d->free, sizeof(*d->detector_velocity));
00485 d->average_detector_velocity[0]=0.0;
00486 d->average_detector_velocity[1]=0.0;
00487 d->average_detector_velocity[2]=0.0;
00488 for(i=0;i<d->free;i++){
00489         /* middle of the 30min interval */
00490         get_detector_vel(d->gps[i]+(int)(d->coherence_time*0.5),&(d->detector_velocity[3*i]));
00491                 
00492         d->average_detector_velocity[0]+=d->detector_velocity[3*i];
00493         d->average_detector_velocity[1]+=d->detector_velocity[3*i+1];
00494         d->average_detector_velocity[2]+=d->detector_velocity[3*i+2];
00495         }
00496 d->average_detector_velocity[0]/=d->free;
00497 d->average_detector_velocity[1]/=d->free;
00498 d->average_detector_velocity[2]/=d->free;
00499 fprintf(LOG,"dataset %s average detector velocity: %g %g %g\n", d->name, 
00500         d->average_detector_velocity[0],
00501         d->average_detector_velocity[1],
00502         d->average_detector_velocity[2]);
00503 det_vel_dec=atan2f(d->average_detector_velocity[2], 
00504         sqrt(d->average_detector_velocity[0]*d->average_detector_velocity[0]+
00505                 d->average_detector_velocity[1]*d->average_detector_velocity[1]));
00506 det_vel_ra=atan2f(d->average_detector_velocity[1], d->average_detector_velocity[0]);
00507 if(det_vel_ra<0)det_vel_ra+=2.0*M_PI;
00508 fprintf(LOG,"dataset %s average detector velocity RA (degrees) : %f\n", d->name, det_vel_ra*180.0/M_PI);
00509 fprintf(LOG,"dataset %s average detector velocity DEC (degrees): %f\n", d->name, det_vel_dec*180.0/M_PI);
00510 fprintf(stderr,"dataset %s average detector velocity RA (degrees) : %f\n", d->name, det_vel_ra*180.0/M_PI);
00511 fprintf(stderr,"dataset %s average detector velocity DEC (degrees): %f\n", d->name, det_vel_dec*180.0/M_PI);
00512 
00513 orbital_axis[0]=0.0;
00514 orbital_axis[1]=-sin(M_PI*23.44/180.0);
00515 orbital_axis[2]=cos(M_PI*23.44/180.0);
00516 
00517 /* crossproduct gives the vector perpedicular to both the average doppler shift and
00518   orbital axis */
00519 d->band_axis[0]=orbital_axis[1]*d->average_detector_velocity[2]-orbital_axis[2]*d->average_detector_velocity[1];
00520 d->band_axis[1]=orbital_axis[2]*d->average_detector_velocity[0]-orbital_axis[0]*d->average_detector_velocity[2];
00521 d->band_axis[2]=orbital_axis[0]*d->average_detector_velocity[1]-orbital_axis[1]*d->average_detector_velocity[0];
00522 
00523 /* Normalize */
00524 d->band_axis_norm=sqrt(d->band_axis[0]*d->band_axis[0]+
00525         d->band_axis[1]*d->band_axis[1]+
00526         d->band_axis[2]*d->band_axis[2]);
00527 /* replace 0.0 with something more reasonable later */
00528 if(d->band_axis_norm<=0.0){
00529         d->band_axis[0]=0.0;
00530         d->band_axis[1]=0.0;
00531         d->band_axis[2]=1.0;
00532         } else {
00533         d->band_axis[0]/=d->band_axis_norm;
00534         d->band_axis[1]/=d->band_axis_norm;
00535         d->band_axis[2]/=d->band_axis_norm;
00536         }
00537 /* 
00538   Normalize band_axis_norm so it matches the definition of \vec{u}
00539 */
00540 d->band_axis_norm*=2.0*M_PI/(365.0*24.0*3600.0);
00541 
00542 fprintf(LOG, "dataset %s auto band axis norm: %g\n", d->name, d->band_axis_norm);
00543 fprintf(LOG, "dataset %s maximum S contribution from Doppler shifts: %g\n", d->name, d->band_axis_norm*(d->first_bin+d->nbins*0.5)/d->coherence_time);
00544 
00545 if(args_info.band_axis_norm_given) {
00546         d->band_axis_norm=args_info.band_axis_norm_arg;
00547         }
00548 
00549 fprintf(LOG, "dataset %s actual band axis norm: %g\n", d->name, d->band_axis_norm);
00550 
00551 d->large_S=6.0/(d->coherence_time*(d->gps[d->free-1]-d->gps[0]+d->coherence_time));
00552 
00553 fprintf(LOG, "dataset %s auto large S: %g\n", d->name, d->large_S);
00554 
00555 if(args_info.large_S_given){
00556         d->large_S=args_info.large_S_arg;
00557         }
00558 fprintf(LOG, "dataset %s large S: %g\n", d->name, d->large_S);
00559         
00560 
00561 fprintf(LOG,"dataset %s auto band axis: %g %g %g\n", d->name, 
00562         d->band_axis[0],
00563         d->band_axis[1],
00564         d->band_axis[2]);
00565 fprintf(stderr,"dataset %s auto band axis: %g %g %g\n", d->name, 
00566         d->band_axis[0],
00567         d->band_axis[1],
00568         d->band_axis[2]);
00569 
00570 fprintf(LOG, "dataset %s band_axis: %s\n", d->name, args_info.band_axis_arg);
00571 fprintf(stderr, "dataset %s band_axis: %s\n", d->name, args_info.band_axis_arg);
00572 if(!strcasecmp(args_info.band_axis_arg, "equatorial")){
00573         d->band_axis[0]=0.0;
00574         d->band_axis[1]=0.0;
00575         d->band_axis[2]=1.0;    
00576         } else
00577 if(!strncasecmp(args_info.band_axis_arg, "explicit", 8)){
00578         int q;
00579         q=sscanf(args_info.band_axis_arg+8, "(%lf,%lf,%lf)", 
00580                 &(d->band_axis[0]),
00581                 &(d->band_axis[1]),
00582                 &(d->band_axis[2]));
00583         if(q!=3){
00584                 fprintf(stderr,"Warning ! In dataset %s not all explicit band axis values were assigned. Format error ?\n", d->name);
00585                 fprintf(LOG,"Warning ! In dataset %s not all explicit band axis values were assigned. Format error ?\n", d->name);
00586                 }
00587         }
00588         
00589 fprintf(LOG,"dataset %s actual band axis: %g %g %g\n", d->name, 
00590         d->band_axis[0],
00591         d->band_axis[1],
00592         d->band_axis[2]);
00593 fprintf(stderr,"dataset %s actual band axis: %g %g %g\n", d->name, 
00594         d->band_axis[0],
00595         d->band_axis[1],
00596         d->band_axis[2]);
00597 
00598 band_axis_dec=atan2f(d->band_axis[2], 
00599         sqrt(d->band_axis[0]*d->band_axis[0]+d->band_axis[1]*d->band_axis[1]));
00600 band_axis_ra=atan2f(d->band_axis[1], d->band_axis[0]);
00601 
00602 if(band_axis_ra<0)band_axis_ra+=2.0*M_PI;
00603 fprintf(stderr,"dataset %s band axis RA (degrees) : %f\n", d->name, band_axis_ra*180.0/M_PI);
00604 fprintf(stderr,"dataset %s band axis DEC (degrees): %f\n", d->name, band_axis_dec*180.0/M_PI);
00605 fprintf(LOG,"dataset %s band axis RA (degrees) : %f\n", d->name, band_axis_ra*180.0/M_PI);
00606 fprintf(LOG,"dataset %s band axis DEC (degrees): %f\n", d->name, band_axis_dec*180.0/M_PI);
00607 }
00608 
00609 /* Note: this messes with tm variable,
00610   tm[i]=exp(log(10)*TMedians[i])/Modulation[i] */
00611 float FindCutOff(float *tm, int nsegments)
00612 {
00613 int i;
00614 double sum,sum_squared,mean,sigma;
00615 double best_cutoff,smallest_sigma;
00616 double a;
00617 int best_i;
00618 sort_floats(tm, nsegments);
00619 sum=0;
00620 sum_squared=0;
00621 best_i=0;
00622 smallest_sigma=10;
00623 best_cutoff=tm[0];
00624 for(i=0;i<nsegments;i++) {
00625         a=tm[i]/tm[0];
00626         sum+=a;
00627         sum_squared+=a*a;
00628         mean=sum/(i+1);
00629         sigma=10*sqrt((sum_squared))/(i+1);
00630         
00631         if(sigma<smallest_sigma) {
00632                 smallest_sigma=sigma;
00633                 best_i=i;
00634                 best_cutoff=tm[i];
00635                 }
00636         }
00637 //fprintf(stderr,"Cutoff: i=%d sigma=%g cutoff=%g (%g,%g,..)\n",best_i, smallest_sigma, best_cutoff,tm[0],tm[1]);
00638 return best_cutoff;
00639 }
00640 
00641 void apply_hanning_filter(DATASET *d)
00642 {
00643 int i,k;
00644 float *tmp, *p;
00645 tmp=do_alloc(d->nbins, sizeof(*tmp));
00646 for(i=0;i<d->free;i++) {
00647         p=&(d->re[i*d->nbins]);
00648 
00649         /* wrap around, just so that we don't have 0 exactly */
00650         tmp[0]=p[0]-(p[d->nbins-1]+p[1])*0.5;
00651         tmp[d->nbins-1]=p[d->nbins-1]-(p[d->nbins-2]+p[0])*0.5;
00652 
00653         for(k=1;k<(d->nbins-1);k++) {
00654                 tmp[k]=p[k]-(p[k-1]+p[k+1])*0.5;
00655                 }
00656         memcpy(p, tmp, nbins*sizeof(*p));       
00657         }
00658 for(i=0;i<d->free;i++) {
00659         p=&(d->im[i*d->nbins]);
00660 
00661         /* wrap around, just so that we don't have 0 exactly */
00662         tmp[0]=p[0]-(p[d->nbins-1]+p[1])*0.5;
00663         tmp[d->nbins-1]=p[d->nbins-1]-(p[d->nbins-2]+p[0])*0.5;
00664 
00665         for(k=1;k<(d->nbins-1);k++) {
00666                 tmp[k]=p[k]-(p[k-1]+p[k+1])*0.5;
00667                 }
00668         memcpy(p, tmp, nbins*sizeof(*p));       
00669         }
00670 free(tmp);
00671 }
00672 
00673 typedef struct {
00674         int index;
00675         INT64 gps;
00676         } ELEMENT;
00677 
00678 int element_cmp(ELEMENT *e1, ELEMENT *e2)
00679 {
00680 if(e1->gps<e2->gps)return(-1);
00681 if(e1->gps>e2->gps)return(1);
00682 return 0;
00683 }
00684 
00685 void sort_dataset(DATASET *d)
00686 {
00687 ELEMENT *p;
00688 float *bin_re, *bin_im;
00689 INT64 *gps;
00690 int i, k;
00691 
00692 p=do_alloc(d->free, sizeof(*p));
00693 for(i=0;i<d->free;i++) {
00694         p[i].index=i;
00695         p[i].gps=d->gps[i];
00696         }
00697 
00698 qsort(p, d->free, sizeof(*p), element_cmp);
00699 
00700 bin_re=do_alloc(d->free*d->nbins, sizeof(*bin_re));
00701 for(i=0;i<d->free;i++) {
00702         k=p[i].index;
00703         memcpy(&(bin_re[i*d->nbins]), &(d->re[k*d->nbins]), d->nbins*sizeof(*bin_re));
00704         }
00705 free(d->re);
00706 d->re=bin_re;
00707 
00708 bin_im=do_alloc(d->free*d->nbins, sizeof(*bin_im));
00709 for(i=0;i<d->free;i++) {
00710         k=p[i].index;
00711         memcpy(&(bin_im[i*d->nbins]), &(d->im[k*d->nbins]), d->nbins*sizeof(*bin_im));
00712         }
00713 free(d->im);
00714 d->im=bin_im;
00715 
00716 gps=do_alloc(d->free, sizeof(*gps));
00717 for(i=0;i<d->free;i++) {
00718         k=p[i].index;
00719         gps[i]=d->gps[k];
00720         }
00721 free(d->gps);
00722 d->gps=gps;
00723 
00724 d->size=d->free;
00725 
00726 free(p);
00727 }
00728 
00729 void veto_sfts(DATASET *d)
00730 {
00731 int i, j;
00732 float power, *x, *y;
00733 d->sft_veto=do_alloc(d->free, sizeof(*d->sft_veto));
00734 for(i=0;i<d->free;i++) {
00735         d->sft_veto[i]=0;
00736 
00737         if(d->expTMedians[i]<d->veto_level) {
00738                 d->sft_veto[i]=1;
00739                 continue;
00740                 }
00741 
00742         x=&(d->re[i*d->nbins]);
00743         y=&(d->im[i*d->nbins]);
00744         for(j=0;j<d->nbins;j++) {
00745                 power=(*x)*(*x)+(*y)*(*y);
00746                 if(log10(power)>d->TMedians[i]+d->veto_spike_level) {
00747                         d->sft_veto[i]=2;
00748                         break;
00749                         }
00750                 x++;
00751                 y++;
00752                 }
00753         }
00754 }
00755 
00756 typedef struct {
00757         int point;
00758         DATASET *d;
00759         
00760         } CUTOFF_DATA;
00761 
00762 void cutoff_cruncher(int thread_id, CUTOFF_DATA *data)
00763 {
00764 int j, m;
00765 float *tm;
00766 tm=do_alloc(data->d->free, sizeof(*tm));
00767 for(m=0;m<ntotal_polarizations;m++) {
00768 /*      if(patch_grid->band[i]<0){
00769                 d->polarizations[m].patch_CutOff[i]=0.0;
00770                 continue;
00771                 }*/
00772         if(!do_CutOff) {
00773                 data->d->polarizations[m].patch_CutOff[data->point]=1e30;
00774                 continue;
00775                 }
00776         for(j=0;j<data->d->free;j++)tm[j]=1.0/(sqrt(data->d->expTMedians[j])*AM_response(j, patch_grid, data->point, data->d->polarizations[m].AM_coeffs));
00777         data->d->polarizations[m].patch_CutOff[data->point]=FindCutOff(tm, data->d->free);
00778         }
00779 free(tm);
00780 }
00781 
00782 static int validate_dataset(DATASET *d)
00783 {
00784 int i,j, m, k;
00785 float *tm;
00786 CUTOFF_DATA *cd;
00787 
00788 if(d->validated)return 1;
00789 fprintf(stderr, "Validating dataset \"%s\"\n", d->name);
00790 fprintf(stderr, "Found %d segments\n", d->free);
00791 
00792 fprintf(LOG, "dataset %s nsegments : %d\n", d->name, d->free);
00793 fprintf(LOG, "dataset %s detector : %s\n", d->name, d->detector);
00794 
00795 if(d->free<1){
00796         /* free large chunks of ram that might have been reserved */
00797         if(d->size>0) {
00798                 free(d->gps);
00799                 free(d->re);
00800                 free(d->im);
00801                 d->gps=NULL;
00802                 d->re=NULL;
00803                 d->im=NULL;
00804                 }
00805         return 0;
00806         }
00807 
00808 if(!strcmp(d->detector, "unknown")) {
00809         fprintf(stderr, "Each dataset must specify detector being used\n");
00810         return 0;
00811         }
00812 
00813 get_detector(d->detector);
00814 
00815 sort_dataset(d);
00816 
00817 if(fake_injection) {
00818         gsl_integration_workspace *giw;
00819         double accumulated_phase, current_phase, start_time;
00820         int workspace_size=10000;
00821 
00822         fprintf(stderr, "Injecting fake signal.\n");
00823         fprintf(LOG, "Injecting fake signal.\n");
00824         giw=gsl_integration_workspace_alloc(workspace_size);
00825 
00826         start_time=args_info.fake_ref_time_arg;
00827         accumulated_phase=0;
00828         for(i=0;i<d->free;i++) {
00829                 current_phase=compute_phase(giw, workspace_size, start_time, d->gps[i]);
00830                 inject_fake_signal(d, i, accumulated_phase+current_phase);
00831                 if(fabs(d->gps[i]-start_time)>PHASE_ACCUMULATION_TIMEOUT) {
00832                         start_time=d->gps[i];
00833                         accumulated_phase+=current_phase;
00834                         }
00835                 }
00836         gsl_integration_workspace_free(giw);
00837         }
00838 
00839 /* compute_power(d); */
00840 
00841 /* compute time from the start of the run */
00842 d->hours=do_alloc(d->free, sizeof(*(d->hours)));
00843 d->hours_d=do_alloc(d->free, sizeof(*(d->hours_d)));
00844 for(i=0;i<d->free;i++){
00845         d->hours[i]=(1.0*(d->gps[i]-d->gps[0]))/3600.0;
00846         d->hours_d[i]=(1.0*(d->gps[i]-d->gps[0]))/3600.0;
00847         }
00848         
00849 /* compute frequency array */
00850 d->frequencies=do_alloc(d->nbins, sizeof(*(d->frequencies)));
00851 d->freq_d=do_alloc(d->nbins, sizeof(*(d->freq_d)));
00852 for(i=0;i<d->nbins;i++){
00853         d->freq_d[i]=(1.0*(d->first_bin+i))/d->coherence_time;
00854         d->frequencies[i]=(1.0*(d->first_bin+i))/d->coherence_time;
00855         }
00856 
00857 compute_detector_speed(d);
00858 
00859 d->TMedians=do_alloc(d->free, sizeof(*(d->TMedians)));
00860 d->expTMedians=do_alloc(d->free, sizeof(*(d