ACQ2XX_API
Acq132.h
Go to the documentation of this file.
00001 /* ------------------------------------------------------------------------- */
00002 /* Acq132.h : interface for ACQ132 BURST MODE decoder                        */
00003 /* ------------------------------------------------------------------------- */
00004 /*   Copyright (C) 2009 Peter Milne, D-TACQ Solutions Ltd
00005  *                      <Peter dot Milne at D hyphen TACQ dot com>
00006  *                      http://www.d-tacq.com/
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of Version 2 of the GNU General Public License 
00010     as published by the Free Software Foundation;
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
00020 /* ------------------------------------------------------------------------- */
00021 
00022 #ifndef __ACQ132_H__
00023 #define __ACQ132_H__
00024 
00025 #include <map>
00026 #include <vector>
00027 #include <string>
00028 
00029 #include "AcqType.h"
00030 
00031 #define CH_QUAD 4
00032 
00033 #define LEFT    'L'
00034 #define RIGHT   'R'
00035 
00036 #define SCAN_A  'A'
00037 #define SCAN_B  'B'
00038 #define SCAN_C  'C'
00039 #define SCAN_D  'D'
00040 
00041 #define FIFOSAM 128
00042 
00043 #define CHANROW 8
00044 
00045 using namespace std;
00046 
00047 #define MAXDECIM        16
00048 #define PRESCALE        4
00049 
00050 #define TBLOCK_ELEMS (0x600000/32/sizeof(short))
00051 
00052 #define NSEC_PER_MSEC   1000000
00053 
00054 class Acq132DataModel;
00055 
00056 class Channel {
00057         string dump_path;
00058         string name;
00059         string fileName;
00060 
00061         string& makeFileName();
00062 public:
00063         static const char* dump_mode;
00064 
00065         const int ch;
00066         vector<short> data;
00067 
00068         Channel(int _ch);
00069         void print();
00070         void dump(const string& root);
00071         void dump(const string& root, unsigned s1, unsigned s2);
00072         const string* getDumpPath() const { return &dump_path; }
00073 
00074         void clear();
00075 };
00076 
00077 
00078 class EventSignature {
00079 
00080 protected:
00081         short raw[CHANROW];
00082         const unsigned long sample_cursor;
00083         int has_timestamp;
00084 
00085         EventSignature(short _raw[], unsigned long _sample_cursor);
00086 public:
00087         virtual ~EventSignature() {}
00088 
00089         virtual unsigned getSampleCursor() { return sample_cursor; }
00090         unsigned getRawSampleCursor() { return sample_cursor; }
00091         virtual unsigned getCount() const = 0;
00092         virtual unsigned getSamplesInPulse(EventSignature *es1);
00093 
00094         static EventSignature*
00095                 create(short _raw[], unsigned long _sample_cursor);
00096                 /** Factory - returns 0 if not an ES */
00097 
00098         const short* getRaw(void) const {
00099                 return raw;
00100         }       
00101 
00102         bool hasTimeStamp(void) const {
00103                 return has_timestamp;
00104         }
00105 
00106         virtual void print(void) { }
00107 };
00108 
00109 class Quad {
00110         Channel* channels[CH_QUAD];
00111         Channel* unique_channels[CH_QUAD];
00112         int max_ch;
00113         int oversample;
00114         const char scan;
00115         const char lr;
00116         int speed;
00117 
00118         void setChannels(string mask);
00119 public:
00120         Quad(char _scan, char _lr, string mask);
00121 
00122         char getScan() const { return scan; }   
00123 
00124         void print();
00125 
00126         void consume(int ic, short raw);
00127 
00128         void dump(const string& root);
00129         void dump(const string& root, unsigned s1, unsigned s2);
00130 
00131         void clear();
00132         friend class DQuad;
00133 };
00134 
00135 
00136 static string stringFromChar(const char c)
00137 {
00138         static char s[2];
00139         s[0] = c;
00140         s[1] = '\0';
00141         return *(new string(s));
00142 }
00143 
00144 class DQuad {
00145         Acq132DataModel& parent;
00146         const string id;
00147         const string mask;
00148         Quad left;
00149         Quad right;
00150         unsigned long sample_cursor;
00151 
00152         const double clock_interval;
00153         const long _tsample;
00154 
00155         unsigned first_s1;
00156 
00157         DQuad(Acq132DataModel& _parent, char _scan, string _mask)
00158                 : parent(_parent), id(stringFromChar(_scan)), mask(_mask),
00159                 left(_scan, LEFT, mask),
00160                 right(_scan, RIGHT, mask),
00161                 sample_cursor(0),
00162                 clock_interval(PRESCALE * Clock::sample_clock_ns),
00163 /* @@todo .. valid multirate .. but more commonly sample_clock is OUTPUT CLOCK
00164                 _tsample((long)(Clock::sample_clock_ns * MAXDECIM/left.speed))
00165 */
00166                 _tsample((long)Clock::sample_clock_ns),
00167                 first_s1(0),
00168                 eventSignatures(),
00169                 eventOffsets()
00170         {
00171         }                       
00172 
00173         static vector<DQuad*> instances;
00174 
00175         int dumpES(const string& root);
00176         void dumpTimebasePulse(File& ft, double ns, int samples_in_pulse,
00177                 unsigned tsample);
00178         double dumpTimebaseUntil(
00179                         File& ft, double t1, 
00180                         unsigned& begin, unsigned end, int div);
00181         void dumpTimebase(const string& root, unsigned ess = 0);
00182         void dumpTimebaseDR(const string& root);
00183         void dumpTimebase(DumpDef& dd, EventSignature& es, unsigned s1, unsigned s2);
00184         void linkTimebase(const string& root, Quad& quad);
00185         vector<EventSignature *> eventSignatures;
00186         vector<int> eventOffsets;
00187 
00188 public:
00189         static DQuad* instance(Acq132DataModel& parent, char scan, string mask);
00190 
00191 
00192         char getScan() const { return left.getScan(); }
00193 
00194         void consume(short raw_row[]);
00195 
00196         void print();
00197         void dump(const string& root, unsigned ess = 0);
00198         void dump(DumpDef& dd);
00199 
00200         void addES(EventSignature* es, int event_offset);
00201 
00202         unsigned long tsample() {
00203                 return _tsample;
00204         }
00205         double startNS(EventSignature* es) const {
00206                 return clock_interval * es->getCount();
00207         }
00208 
00209         unsigned long getCursor() const {
00210                 return sample_cursor;
00211         }
00212 
00213         int scanES(const string& root);
00214         /**< comb ES list, looking for and removing duplicates */
00215 
00216         vector<int>& getEvents() {
00217                 return eventOffsets;
00218         }
00219 
00220         void clear();
00221 };
00222 
00223 #define MASK32 \
00224   "11111111111111111111111111111111"
00225 //"12345678901234567890123456789012"
00226 
00227 #define ACQ132_DEFSCAN "DCBA"
00228 
00229 class Acq132DataModel {
00230         map<int, Channel*> the_channels;
00231         vector<DQuad*> scanlist;
00232         vector<int> eventOffsets;                       /* event offsets */
00233         int maxsamples;
00234         int actual_samples;
00235 
00236         void trimSamples();
00237 
00238         void processSubBlock(short *data, int ndata);
00239         void processAll(short *data, int ndata);
00240 
00241 public:
00242         bool timed_at_event;
00243         unsigned msecs_start;
00244 
00245         Acq132DataModel(
00246                 string _model_def, 
00247                 string _scanlist = ACQ132_DEFSCAN, 
00248                 string _channelMask = MASK32);
00249         virtual ~Acq132DataModel() {}
00250 
00251         void print();
00252         void process(short *data, int ndata);
00253         void dump(const string& root, unsigned ess = 0);
00254         void dump(DumpDef& dd);
00255         virtual void setMaxsamples(int _maxsamples) {
00256                 maxsamples = _maxsamples;
00257         }
00258         vector<short>& getChannel(int ichan);
00259         virtual vector<int>& getEvents();
00260 
00261         void clear();
00262 
00263         void setWallClockPolicy(unsigned _msecs_start, bool timed_at_event);
00264 };
00265 
00266 
00267 #endif