ACQ2XX_API
acq_demux.cpp
Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- */
00002 /* file acq_demux.cpp                                                        */
00003 /* ------------------------------------------------------------------------- */
00004 /*   Copyright (C) 2010 Peter Milne, D-TACQ Solutions Ltd
00005  *                      <Peter dot Milne at D hyphen TACQ dot com>
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of Version 2 of the GNU General Public License
00008     as published by the Free Software Foundation;
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
00018 /* ------------------------------------------------------------------------- */
00019 
00020 /** @file acq_demux.cpp demuxes (de-channelizes) acqXXX raw data.
00021  * 
00022 <pre>
00023  Usage: acq_demux [options] RAWFILES
00024         Where RAWFILES are file names containing raw data.
00025         Typically tblock uploads 000, 001, 002 ...
00026        
00027         options:
00028         -d --debug level : set debugging/
00029         -a --acq_type def-file : define ACQ type using def-file
00030         -n --nsamples samples : preset number of samples in output
00031         -T --sample_clock_ns  : define inter sample interval in nano secs
00032         -C --ChanneSpeedMask  : multirate - ACQ132 only
00033         -o --WorkingDir::outbase          : save output in DirFile format RAWFILE.COOKED/
00034         --dual-rate div1,div2 
00035 </pre>
00036 * DirFile output is compatible with kst.
00037 <pre>
00038 Typical def file:
00039 [pgm@hoy API]$ cat acq132.def 
00040 ACQ=acq132
00041 WORD_SIZE=2
00042 AICHAN=32
00043 </pre>
00044 */
00045 
00046 
00047 #include <assert.h>
00048 #include <iostream>
00049 #include <map>
00050 #include <vector>
00051 #include <set>
00052 
00053 
00054 #include <stdlib.h>
00055 #include <libgen.h>     /* dirname() */
00056 #include <unistd.h>
00057 #include <errno.h>
00058 
00059 #include <fcntl.h>
00060 #include <sys/mman.h>
00061 #include <sys/stat.h>
00062 #include <sys/types.h>
00063 #include <sys/stat.h>
00064 
00065 
00066 #include "popt.h"
00067 
00068 const char *VERID = "acq_demux $Revision: 1.48 $ B1020";
00069 
00070 char channel_mask[80];
00071 char scan_list[16];
00072 
00073 
00074 #include "local.h"
00075 
00076 #include "acq_demux.h"
00077 #include "AcqType.h"
00078 #include "AcqDataModel.h"
00079 
00080 #include "CommandBuffer.h"
00081 #include "Timer.h"
00082 #include "WorkingDir.h"
00083 
00084 #include "ProcessController.h"
00085 
00086 extern "C" {
00087 int acq200_debug = 0;
00088 };
00089 
00090 int nsamples;
00091 const char *csm;
00092 const char *acq_def_file = "acq_type.def";
00093 
00094 const char *dual_rate_def = 0;
00095 
00096 
00097 NewEventSignature* userStartTime;
00098 
00099 static poptContext processOpts(int argc, const char** argv)
00100 {
00101         char *infile = 0;
00102         static double start_time;
00103         int start_time_set = false;
00104         char *logfile;
00105 
00106         static struct poptOption opt_table[] = {
00107         { "debug",              'd', POPT_ARG_INT, &acq200_debug,       0 },
00108         { "acq_type",           'a', POPT_ARG_STRING, &acq_def_file,    0 },
00109         { "input",              'i', POPT_ARG_STRING, &infile,          'i' },
00110         { "logfile",            'L', POPT_ARG_STRING, &logfile,         'L' },
00111         { "nsamples",           'n', POPT_ARG_INT, &nsamples,           0 },
00112         { "sample_clock_ns",    'T', POPT_ARG_DOUBLE, 
00113                                                   &Clock::sample_clock_ns, 'T'},
00114         { "ChannelSpeedMask",   'C', POPT_ARG_STRING, &csm,             'C' },
00115         { "outbase",'O', POPT_ARG_STRING, &WorkingDir::outbase, 0 },
00116         { "dual-rate",           0,  POPT_ARG_STRING, &dual_rate_def,    'd' },
00117         { "cleanup",             0,  POPT_ARG_INT, &WorkingDir::cleanup, 0 },
00118         { "maxlen",             'm', POPT_ARG_INT, &Args::maxlen, 0 },
00119         { "pre",                0,  POPT_ARG_INT, &Args::pre, 0 },
00120         { "post",               0, POPT_ARG_INT, &Args::post, 0 },
00121         { "startoff",           0, POPT_ARG_INT, &Args::startoff, 0 },
00122         { "start-time",         't', POPT_ARG_DOUBLE, &start_time, 't' },
00123         POPT_AUTOHELP
00124         POPT_TABLEEND
00125         };
00126 
00127         if (getenv("ACQ200_DEBUG")){
00128                 acq200_debug = atoi(getenv("ACQ200_DEBUG"));
00129         }
00130 
00131         if (getenv("MULTIPLE_TIMEBASE")){
00132                 DumpDef::common_timebase =
00133                                 atoi(getenv("MULTIPLE_TIMEBASE")) ==0;
00134         }
00135         if (getenv("WCP_TIMED_AT_EVENT")){
00136                 AcqDataModel::wallclock_policy = WCP_TIMED_AT_EVENT;
00137         }
00138         poptContext opt_context =
00139                 poptGetContext(argv[0], argc, argv, opt_table, 0);
00140         int rc;
00141 
00142         while((rc = poptGetNextOpt(opt_context)) > 0){
00143                 switch(rc){
00144                 case 'i':
00145                         if (strcmp(infile, "-") == 0){
00146                                 Args::config_fp = stdin;
00147                         }else{
00148                                 Args::config_fp = fopen(infile, "r");
00149                                 if (!Args::config_fp){
00150                                         perror(infile);
00151                                         exit(1);
00152                                 }
00153                         }
00154                         break;
00155                 case 'L':
00156                         if (strcmp(logfile, "-") == 0){
00157                                 Args::log_fp = stdout;
00158                         }else{
00159                                 Args::log_fp = fopen(logfile, "w");
00160                                 if (!Args::log_fp){
00161                                         perror(logfile);
00162                                         exit(1);
00163                                 }else{
00164                                         info("logging to %s", logfile);
00165                                 }
00166                         }
00167                         break;
00168                 case 'd':
00169                         if (sscanf(dual_rate_def, "%d,%d", 
00170                                    &DualRate::div0, &DualRate::div1) != 2){
00171                                 err("usage: dual-rate div0,div1");
00172                                 exit(-1);
00173                         }
00174                 case 'T':
00175 //@@todo                        Clock::sample_clock_ns *= MAXDECIM;
00176 //                      Clock::sample_clock_ns = 1000;  /** @@todo popt bug? */
00177                         break;
00178                 case 't':
00179                         start_time_set = true;
00180                         break;
00181                 default:
00182                         break;
00183                 }
00184         }
00185 
00186         if (start_time_set){
00187                 userStartTime = new UserEventSignature(start_time);
00188         }
00189         return opt_context;
00190 }
00191 
00192 static string &makeIdent(int argc, const char **argv)
00193 {
00194         string *strp = new string();
00195         string& s = *strp;
00196 
00197         s += VERID;
00198         s += "\n";
00199 
00200         for (int ii = 0; ii < argc; ++ii){
00201                 s += argv[ii];
00202                 s += " ";
00203         }
00204         s += "\n";
00205         return *strp;
00206 }
00207 
00208 
00209 
00210 int main(int argc, const char **argv)
00211 {
00212         poptContext opt_context = processOpts(argc, argv);
00213         char namebuf[128];
00214 
00215         strcpy(namebuf, argv[0]);
00216         string pname(basename(namebuf));
00217         
00218         
00219 
00220         AcqDataModel& dataModel = *AcqDataModel::create(
00221                 AcqType::getAcqType(acq_def_file), scan_list, channel_mask);
00222 
00223         dataModel.setIdent(makeIdent(argc, argv));
00224         if (userStartTime){
00225                 dataModel.addEventSignature(userStartTime);
00226         }
00227 
00228         if (nsamples){
00229                 dataModel.setMaxsamples(nsamples);
00230         }
00231 
00232         ProcessController *pc = ProcessController::create(pname, dataModel);
00233 
00234         info("%s %s", pname.c_str(), VERID);
00235 
00236         if (pc){
00237                 pc->run(opt_context);
00238         }
00239 }
00240 
00241 int Args::maxlen;
00242 int Args::startoff;
00243 int Args::pre;
00244 int Args::post;
00245 FILE *Args::config_fp;
00246 FILE *Args::log_fp;