V172X_Params.cc

00001 #include "V172X_Params.hh"
00002 #include "Message.hh"
00003 #include <exception>
00004 #include <stdexcept>
00005 #include <math.h>
00006 
00007 //declare some useful constants
00008 //const double sample_rate =  100.;
00009 //const double V_full_scale = 2.25;
00010 //const int sample_bits = 14;
00011 //const int bytes_per_sample = 2;
00012 
00013 const uint32_t max_14bit = 0x3FFF;
00014 const uint32_t acq_control_set = 0x28;
00015 const uint32_t channels_config_set = 0x10;
00016 //const uint32_t max_samples = 524288;
00017 const int event_size_padding = 8;
00018 const int Mbyte = 1024*1024;
00019 
00020 const uint16_t halfmax14 = 0x1FFF;
00021 const uint16_t halfmax16 = 0x7FFF;
00022 const uint32_t halfmax32 = 0x7FFFFFFF;
00023 using namespace std;
00024 
00025 V172X_ChannelParams::V172X_ChannelParams() : 
00026   ParameterList("V172X_ChannelParams", 
00027                 "Information about a single channel in a CAEN V172X digitizer")
00028 {
00029   RegisterParameter("enabled", enabled=true, 
00030                     "Is this channel active in the current run?");
00031   RegisterParameter("enable_trigger_source", enable_trigger_source=false,
00032                     "Does this channel generat local trigger signals?");
00033   RegisterParameter("enable_trigger_out", enable_trigger_out=false,
00034                     "Does this channel generate trigger out signals?");
00035   RegisterParameter("threshold", threshold = halfmax14,
00036                     "The threshold (in counts) for the signal to trigger on");
00037   RegisterParameter("thresh_time_us", thresh_time_us = 0,
00038                     "Time that the signal must be above/below threshold in order to generate a trigger");
00039   RegisterParameter("dc_offset", dc_offset = halfmax16,
00040                     "DC offset (16 bit range) applied to the signal before digitizing");
00041   RegisterParameter("zs_polarity", zs_polarity = TP_FALLING, "Do we suppress the signal if it is below or above the zs_threshold?");
00042   RegisterParameter("zs_threshold",zs_threshold = halfmax14, "Threshold the signal must cross before it is considered to be non-zero");
00043   RegisterParameter("zs_thresh_time_us",zs_thresh_time_us = 0,"Time a signal must be above the zs_threshold before it counts");
00044   RegisterParameter("zs_pre_samps", zs_pre_samps = 10, 
00045                     "Number of samples to save before a ZLE removed block");
00046   RegisterParameter("zs_post_samps", zs_post_samps = 10, 
00047                     "Number of samples to save after a ZLE removed block");
00048   
00049   RegisterParameter("label",label="x", 
00050                     "A descriptive label for the channel");
00051 }
00052 
00053 V172X_BoardParams::V172X_BoardParams() : 
00054   ParameterList("V172X_BoardParams",
00055                 "Information about a single CAEN V172X Digitizer")
00056 {
00057   RegisterParameter("enabled", enabled = false,
00058                     "Is this board active in this run?");
00059   RegisterParameter("address", address = 0xFFFF0000,
00060                     "Address of the board on the VME crate (set in hardware)");
00061   RegisterParameter("link", link = 0,
00062                     "Board optical link number");
00063   RegisterParameter("usb", usb = false,
00064                     "Connect through USB instead of optical link?");
00065   RegisterParameter("chainindex", chainindex=0, 
00066                     "Order of board on a fiber daisy chain connection");
00067   RegisterParameter("id", id = -1, "Software id of the board");
00068   RegisterParameter("board_type", board_type = OTHER,
00069                     "Specific model of digitizer (V1720, V1724, V1721)");
00070   RegisterParameter("nchans", nchans = MAXCHANS, 
00071                     "actual number of channels on this unit");
00072   RegisterParameter("v_full_scale", v_full_scale = 2,
00073                     "Full scale range in voltage of the digitizer input");
00074   RegisterParameter("stupid_size_factor", stupid_size_factor = 1);
00075   RegisterParameter("sample_bits", sample_bits = 12,
00076                     "Sampling depth of the ADC conversion");
00077   RegisterParameter("max_sample_rate", max_sample_rate = 250.,
00078                     "Maximum number of samples recorded per microsecond");
00079   RegisterParameter("mem_size", mem_size = 1,
00080                     "Maximum size of onboard buffer, in MSamples/channel");
00081   RegisterParameter("bytes_per_sample", bytes_per_sample = 2,
00082                     "Number of aligned bytes needed for a single sample");
00083   RegisterParameter("event_size_bytes", event_size_bytes = 0,
00084                     "Expected size of a single event in bytes");
00085   RegisterParameter("ns_per_clocktick", ns_per_clocktick = 8,
00086                     "Time between each tick of the onboard trigger clock");
00087   RegisterParameter("enable_software_trigger", enable_software_trigger=true,
00088                     "Can this board receive triggers from the VME plane (from the computer)?");
00089   RegisterParameter("enable_software_trigger_out",
00090                     enable_software_trigger_out = true,
00091                     "Does this board repeat VME triggers to the trigger-out signal?");
00092   RegisterParameter("enable_external_trigger", enable_external_trigger=true,
00093                     "Does this board trigger on the trigger-in signal?");
00094   RegisterParameter("enable_external_trigger_out",
00095                     enable_external_trigger_out = true,
00096                     "Does this board repeat the trigger-in to trigger-out?");
00097   RegisterParameter("local_trigger_coincidence",local_trigger_coincidence = 0,
00098                     "Number of channels after the first necessary to generate a trigger");
00099   RegisterParameter("pre_trigger_time_us", pre_trigger_time_us = 1,
00100                     "Length of buffer time to to store before the trigger");
00101   RegisterParameter("post_trigger_time_us", post_trigger_time_us = 30,
00102                     "Length of time after the trigger to store");
00103   RegisterParameter("downsample_factor", downsample_factor = 1,
00104                     "No longer implemented in CAEN firmware; kept for compatibility only!");
00105   RegisterParameter("trigger_polarity", trigger_polarity = TP_FALLING,
00106                     "Determines whether to generate trigger when the signal is above or below the trigger threshold");
00107   RegisterParameter("count_all_triggers", count_all_triggers = true,
00108                     "Do we increment the trigger counter when overlapping triggers come in, or the buffer is full?");
00109   RegisterParameter("zs_type", zs_type = NONE,
00110                     "Which type of zero suppression to use (should be NONE)");
00111   RegisterParameter("enable_trigger_overlap", enable_trigger_overlap = false,
00112                     "Do we generate partial triggers if two come in too close to each other?");
00113   RegisterParameter("signal_logic", signal_logic = NIM,
00114                     "Type of logic (NIM or TTL) for external signals");
00115   RegisterParameter("enable_test_pattern", enable_test_pattern = false,
00116                     "Generate a triangle wave on the channels instead of measure real signals?");
00117   //RegisterParameter("acq_control_val", 
00118   //acq_control_val =  ( 1<<4 * (downsample_factor > 1) + 
00119   //1<<3 * count_all_triggers ) ); 
00120   for(int i=0; i<MAXCHANS; i++){
00121     char key[20];
00122     sprintf(key,"channel%d",i);
00123     RegisterParameter(key,channel[i]);
00124   }  
00125 }
00126 
00127 V172X_Params::V172X_Params() : ParameterList("V172X_Params")
00128 {
00129   RegisterParameter("align64", align64 = true,
00130                     "Do we include an extra empty sample when using 64-bit size words?");
00131   RegisterParameter("trigger_timeout_ms", trigger_timeout_ms = 3000,
00132                     "Time to wait for a trigger before timing out");
00133   RegisterParameter("max_mem_size", max_mem_size  = 209715200,
00134                     "Maximum amount of memory we're allowed to use for the raw event buffer");
00135   RegisterParameter("no_low_mem_warn",no_low_mem_warn = false,
00136                     "Should we suppress the warning generated when the raw event buffer is full?");
00137   RegisterParameter("send_start_pulse",send_start_pulse = false,
00138                     "Do we tell the digitizers to wait to start the event until a synchornize pulse is sent (true), or start immediately (false)");
00139   RegisterParameter("auto_trigger", auto_trigger = false,
00140                     "Do we automatically generate a trigger if timeout occurrs?");
00141   RegisterParameter("vme_bridge_link", vme_bridge_link = 0,
00142                     "VME bridge optical link number");
00143   //RegisterParameter("event_size_bytes", event_size_bytes = 0);
00144   //RegisterParameter("enabled_boards", enabled_boards = 0);
00145   //RegisterParameter("enabled_channels", enabled_channels = 0);
00146   for(int i=0; i<nboards; i++){
00147     char key[20];
00148     sprintf(key,"board%d",i);
00149     RegisterParameter(key,board[i]);
00150     board[i].id = i;
00151     for(int j=0; j<board[i].MAXCHANS; j++){
00152       sprintf(key,"b%dch%d",i,j);
00153       board[i].channel[j].label = key;
00154     }
00155   }
00156 }
00157   
00158 int V172X_BoardParams::UpdateBoardSpecificVariables()
00159 {
00160   switch(board_type){
00161   case V1724:
00162     max_sample_rate = 100.;
00163     sample_bits = 14;
00164     bytes_per_sample = 2;
00165     v_full_scale = 2.25;
00166     stupid_size_factor = 1;
00167     ns_per_clocktick = 10;
00168     break;
00169   case V1720:
00170     max_sample_rate = 250;
00171     sample_bits = 12;
00172     bytes_per_sample = 2;
00173     v_full_scale = 2;
00174     stupid_size_factor = 2;
00175     ns_per_clocktick = 8;
00176     break;
00177   case V1721:
00178      max_sample_rate = 1000;
00179     sample_bits = 8;
00180     bytes_per_sample = 1;
00181     v_full_scale = 2;
00182     stupid_size_factor = 1;
00183     ns_per_clocktick = 8;
00184     break;
00185   case V1751:
00186     max_sample_rate = 1000;
00187     sample_bits = 10;
00188     bytes_per_sample = 2;
00189     v_full_scale = 1;
00190     stupid_size_factor = 7;
00191     ns_per_clocktick = 4;
00192     break;
00193   default:
00194     return -1;
00195     
00196   }
00197   return 0;
00198 }
00199 
00200 //Utility functions
00201 //returns sample rate in samples per microsecond
00202 double V172X_BoardParams::GetSampleRate() const
00203 {
00204   //if(downsample_factor > 10) downsample_factor = 10;
00205   return max_sample_rate;
00206 }
00207 
00208 uint32_t V172X_BoardParams::GetPostNSamps() const
00209 {
00210   return (uint32_t)(post_trigger_time_us * GetSampleRate());
00211 }
00212 
00213 uint32_t V172X_BoardParams::GetPreNSamps() const
00214 {
00215   return (uint32_t)(pre_trigger_time_us * GetSampleRate());
00216 }
00217 
00218 uint32_t V172X_BoardParams::GetTotalNSamps() const
00219 {
00220   uint32_t total_nsamps = (uint32_t)
00221     (( pre_trigger_time_us + post_trigger_time_us ) * GetSampleRate());
00222   while( total_nsamps % (4/bytes_per_sample)) total_nsamps++;
00223   //if(total_nsamps%2) total_nsamps++;
00224   return total_nsamps;
00225 }
00226 
00227 uint32_t V172X_BoardParams::GetBufferCode() const
00228 {
00229   int max_samples = mem_size*Mbyte / bytes_per_sample;
00230   if(board_type == V1751)
00231     max_samples = (int)(Mbyte * (mem_size == 0x02 ? 1.835 : 14.4 ));
00232   uint32_t buffer_code = (uint32_t)floor(log2(max_samples / GetTotalNSamps()));
00233   if(buffer_code > 0xA)
00234     buffer_code = 0xA;
00235   return buffer_code;
00236 }
00237 
00238 uint32_t V172X_BoardParams::GetCustomSizeSetting() const
00239 {
00240   if(board_type == V1751)
00241     return GetTotalNSamps()/stupid_size_factor;
00242   return GetTotalNSamps()*bytes_per_sample/
00243     ( sizeof(uint32_t) * stupid_size_factor);
00244 }
00245 
00246 uint32_t V172X_BoardParams::GetPostTriggerSetting() const
00247 {
00248   const int latency = 10;
00249   if(board_type == V1751)
00250     return GetPostNSamps() / 16 - latency;
00251   return GetPostNSamps()/(2*stupid_size_factor) - latency;
00252   
00253 }
00254 
00255 //return the index corresponding to the sample at the trigger time
00256 int V172X_BoardParams::GetTriggerIndex() const
00257 {
00258   return GetPreNSamps();
00259 }
00260 
00261 uint64_t V172X_BoardParams::GetTimestampRange() const
00262 {
00263   return 0x7fffffff * ns_per_clocktick;
00264 }
00265 
00266 int V172X_Params::GetEnabledBoards()
00267 {
00268   enabled_boards = 0;                          
00269   for(int i=0; i<nboards; i++)
00270     if(board[i].enabled) enabled_boards++;
00271   return enabled_boards;
00272 }
00273 
00274 int V172X_Params::GetEnabledChannels()
00275 {
00276   enabled_boards = 0;
00277   enabled_channels = 0;
00278   for(int i=0; i<nboards; i++){
00279     if(!board[i].enabled) continue;
00280     enabled_boards++;
00281     for(int j=0; j<board[i].nchans; j++){
00282       if(board[i].channel[j].enabled) enabled_channels++;
00283     }
00284   }
00285   return enabled_channels;
00286 }
00287 
00288 //Get the max expected event size in bytes
00289 int V172X_Params::GetEventSize()
00290 {
00291   enabled_boards = 0;
00292   enabled_channels = 0;
00293   event_size_bytes = 0;
00294   //event_size_bytes = event_size_padding;
00295   for(int i=0; i<nboards; i++){
00296     if(!board[i].enabled) continue;
00297     enabled_boards++;
00298     board[i].event_size_bytes = event_size_padding + 16; //padding + header
00299     for(int j =0; j<board[i].nchans; j++){
00300       if(board[i].channel[j].enabled){
00301         enabled_channels++;
00302         board[i].event_size_bytes += ( board[i].GetTotalNSamps() * 
00303                                        board[i].bytes_per_sample )
00304           + (board[i].zs_type == ZLE ? 8 : 0 );
00305       }
00306     }//end for loop over channels
00307     event_size_bytes += board[i].event_size_bytes;
00308   }//end for loop over boards
00309   
00310   return event_size_bytes;
00311 }
00312 
00313 std::ostream& operator<<(std::ostream& out, const SIGNAL_LOGIC& logic)
00314 {
00315   if(logic==NIM) 
00316     return out<<"NIM";
00317   else
00318     return out<<"TTL";
00319 }
00320 
00321 std::ostream& operator<<(std::ostream& out, const ZERO_SUPPRESSION_TYPE& zs)
00322 {
00323   if(zs == NONE) 
00324     return out<<"NONE";
00325   else if(zs == ZS_INT)
00326     return out<<"ZS_INT";
00327   else if(zs == ZLE)
00328     return out<<"ZLE";
00329   else
00330     return out<<"ZS_AMP";
00331 }
00332 
00333 std::ostream& operator<<(std::ostream& out, const TRIGGER_POLARITY& pol)
00334 {
00335   if(pol == TP_RISING)
00336     return out<<"TP_RISING";
00337   else 
00338     return out<<"TP_FALLING";
00339 }
00340 
00341 std::ostream& operator<<(std::ostream& out, const BOARD_TYPE& type)
00342 {
00343   if(type == V1724)
00344     return out<<"V1724";
00345   else if (type == V1720)
00346     return out<<"V1720";
00347   else if (type == V1721)
00348     return out<<"V1721";
00349   else if (type == V1751)
00350     return out<<"V1751";
00351   else 
00352     return out<<"OTHER";
00353 }
00354 
00355 std::istream& operator>>(std::istream& in, SIGNAL_LOGIC &logic)
00356 {
00357   std::string temp;
00358   in>>temp;
00359   if(temp == "NIM" || temp == "nim")
00360     logic = NIM;
00361   else if(temp == "TTL" || temp == "ttl")
00362     logic = TTL;
00363   else{
00364     Message e(EXCEPTION);
00365     e<<temp<<" is not a valid value for SIGNAL_LOGIC"<<std::endl;
00366     throw std::invalid_argument(e.str());
00367   }
00368   return in;
00369 }
00370   
00371 std::istream& operator>>(std::istream& in, ZERO_SUPPRESSION_TYPE &zs)
00372 {
00373   std::string temp;
00374   in>>temp;
00375   if(temp == "NONE" || temp == "none")
00376     zs = NONE;
00377   else if(temp == "ZS_INT" || temp == "zs_int")
00378     zs = ZS_INT;
00379   else if(temp == "ZLE" || temp == "zle")
00380     zs = ZLE;
00381   else if(temp == "ZS_AMP" || temp == "zs_amp")
00382     zs = ZS_AMP;
00383   else{
00384     Message e(EXCEPTION);
00385     e<<temp<<" is not a valid value for ZERO_SUPPRESSION_TYPE"<<std::endl;
00386     throw std::invalid_argument(e.str());
00387   }
00388   return in;
00389 }
00390 
00391 std::istream& operator>>(std::istream& in, TRIGGER_POLARITY &pol)
00392 {
00393   std::string temp;
00394   in>>temp;
00395   if(temp == "TP_RISING" || temp == "tp_rising")
00396     pol = TP_RISING;
00397   else if(temp == "TP_FALLING" || temp == "tp_falling")
00398     pol = TP_FALLING;
00399   else{
00400     Message e(EXCEPTION);
00401     e<<temp<<" is not a valid value for TRIGGER_POLARITY"<<std::endl;
00402     throw std::invalid_argument(e.str());
00403   }
00404   return in;
00405 }
00406 
00407 std::istream& operator>>(std::istream& in, BOARD_TYPE& type)
00408 {
00409   std::string temp;
00410   in>>temp;
00411   if(temp == "V1724")
00412      type = V1724;
00413   else if(temp == "V1720")
00414     type = V1720;
00415   else if (temp == "V1721")
00416     type = V1721;
00417   else if (temp == "V1751")
00418     type = V1751;
00419   else if (temp == "OTHER")
00420     type = OTHER;
00421   else{
00422     type = OTHER;
00423     Message e(EXCEPTION);
00424     e<<temp<<" is not a valid value for BOARD_TYPE"<<std::endl;
00425     throw std::invalid_argument(e.str());
00426   }
00427   return in;
00428 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1