Changeset 36 for drsdaq/HVFeedback.cc


Ignore:
Timestamp:
05/07/09 09:16:29 (16 years ago)
Author:
ogrimm
Message:
Various changes, see History.txt
Location:
drsdaq
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • drsdaq

    • Property svn:ignore
      •  

        old new  
        22DRSDAQ.log
        33Dep.d
        4 
         4calib
  • drsdaq/HVFeedback.cc

    r27 r36  
    1717
    1818#define MAX_RETRY 5
    19 
     19#define PIXMAP_LOCATION "../config/PixelMap.txt"
     20
     21//
    2022// Constructor: Initialise feedback
     23//
    2124HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) {
    2225  struct sockaddr_in SocketAddress;
    23  
     26  char Filename[MAX_PATH];
     27
    2428  m = DAQClass;
    25   PixMap = new PixelMap("../config/PixelMap.txt", false);
    26  
     29  PixMap = new PixelMap(PIXMAP_LOCATION, false);
     30
     31  snprintf(Filename,sizeof(Filename),"%s/SlowData/", m->fRawDataPath);
     32  SlowDataClass = new SlowData(m, "HVFB", Filename);
     33
    2734  // Read configuration file
    2835  FILE *File;
     
    3239  else {
    3340    printf("Reading feedback configuration file %s\n", Configfile);
    34     ReadCard("LedTrigBoard",       &fLedTrigBoard,      'I', File);
    35     ReadCard("LedTrigChannel",     &fLedTrigChannel,    'I', File);
    36     ReadCard("LedTrigChip",        &fLedTrigChip,       'I', File);
    37     ReadCard("LedTrigSample",      &fLedTrigSample,     'I', File);
    38     ReadCard("LedTrigThreshold",   &fLedTrigThreshold,  'f', File);
    39     ReadCard("LedSignalSample",    &fLedSignalSample,   'I', File);
    40     ReadCard("LedBaselineSample",  &fLedBaselineSample, 'I', File);
    41     ReadCard("DefaultNumAverage",  &fDefaultNumAverage, 'I', File);
    42     ReadCard("HVControlServer",     fHVControlServer,   's', File);
    43     ReadCard("HVControlPort",      &fHVControlPort,     'I', File);
    44     ReadCard("MaxCmdAckDelay",     &fMaxCmdAckDelay,    'I', File);
     41    ReadCard("TrigBoard",           &fLedTrigBoard,      'I', File);
     42    ReadCard("TrigChannel",         &fLedTrigChannel,    'I', File);
     43    ReadCard("TrigChip",            &fLedTrigChip,       'I', File);
     44    ReadCard("TrigSample",          &fLedTrigSample,     'I', File);
     45    ReadCard("TrigThreshold",       &fLedTrigThreshold,  'f', File);
     46    ReadCard("SignalSample",        &fLedSignalSample,   'I', File);
     47    ReadCard("BaselineSample",      &fLedBaselineSample, 'I', File);
     48    ReadCard("IntHalfWidth",        &fIntHalfWidth,      'U', File);
     49    ReadCard("DefaultNumAverage",   &fDefaultNumAverage, 'I', File);
     50    ReadCard("HVControlServer",      fHVControlServer,   's', File);
     51    ReadCard("HVControlPort",       &fHVControlPort,     'I', File);
     52    ReadCard("MaxCmdAckDelay",      &fMaxCmdAckDelay,    'I', File);
    4553    fclose(File);
    4654  }
     
    4856
    4957  // Initialise
    50   Average    = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    51   Response   = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    52   Target     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels];
    53   Buffer     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 
    54  
     58  Average    = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     59  Sigma      = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     60  Response   = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     61  Target     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]();
     62  Buffer     = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 
     63
     64/*   for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     65    for (int j=0; j<kNumberOfChips; j++)
     66      for (int k=0; k<kNumberOfChannels; k++) {
     67        Response[i][j][k] = 0.0;
     68        Target[i][j][k] = 0.0;
     69      }
     70 */
    5571  Gain = 1;
    5672  SetFBMode(FB_Off);
     
    7793}
    7894
     95//
    7996// Destructor
     97//
    8098HVFeedback::~HVFeedback() {
    8199  if (SocketDescriptor!=-1) {
     
    85103  delete[] Average;     delete[] Response;
    86104  delete[] Target;      delete[] Buffer;
    87   delete PixMap;
    88 }
    89 
    90 
     105  delete SlowDataClass; delete PixMap;
     106}
     107
     108//
    91109// Check if LED trigger present, if yes accumulate feedback data and
    92110// calculate new high voltages if the required number of events is reached.
     111//
    93112bool HVFeedback::ProcessEvent() {
    94   float Correction;
     113  int i,j,k,q;
     114  float Correction, Integral, Difference, EffectiveGain;
    95115 
    96116  // Check for LED trigger channel on given channel and if feedback running
    97117  if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] < fLedTrigThreshold)
    98118    return false;
    99   Count++;
    100119 
    101   // Add signal at LED bin for all channels
    102   for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    103     for (int j=0; j<kNumberOfChips; j++)
    104       for (int k=0; k<kNumberOfChannels; k++)
    105         Average[i][j][k] += (m->WaveForm[i][j][k][fLedSignalSample] - m->WaveForm[i][j][k][fLedBaselineSample])*m->BStruct[i].ScaleFactor;
    106  
     120  // Calculate average signal of LED pulse as integral of signal
     121  for (i=m->FirstBoard; i<=m->LastBoard; i++)
     122    for (j=0; j<kNumberOfChips; j++)
     123      for (k=0; k<kNumberOfChannels; k++) {
     124        for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++)
     125          Integral += (m->WaveForm[i][j][k][fLedSignalSample+q] - m->WaveForm[i][j][k][fLedBaselineSample+q])*m->BStruct[i].ScaleFactor;
     126        Integral /= 2*fIntHalfWidth+1;
     127        Average[i][j][k] += Integral;
     128        Sigma[i][j][k] += pow(Integral,2);
     129      }
     130
     131  if (++Count<NumAverages) return false;
     132
    107133  // Acquired number of event requires action
    108   if (Count==NumAverages) {
    109     for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    110       for (int j=0; j<kNumberOfChips; j++)
    111         for (int k=0; k<kNumberOfChannels; k++) {
    112           Average[i][j][k] /= Count;
    113           switch (FBMode) {
    114             case FB_Active:   // Determine correction from response maxtrix and change voltages
    115               Correction = (Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain;
    116               if(Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty())
    117                 WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);
    118               break;
    119             case FB_Targets:  // Take average as new targets 
    120               Target[i][j][k] = Average[i][j][k];
    121               break;
    122             case FB_ResponseFirst:  // First point of response measurement done 
    123               Buffer[i][j][k] = Average[i][j][k];
    124               if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), Voltage2);
    125               break;
    126             case FB_ResponseSecond: // Determine response from signal variation
    127               if(Buffer[i][j][k] == Average[i][j][k]) {
    128                 m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
    129                 Response[i][j][k] = 0;
    130               }
    131               else Response[i][j][k] = Voltage2/(Buffer[i][j][k]-Average[i][j][k]);
    132               break;
    133             default: break;  // to suppress warning abount not handled enumeration value
    134           }                     
    135         }
    136     switch (FBMode) {
    137       case FB_Active:
    138         m->PrintMessage("HV Feedback: Acted.\n");
    139         break;
    140       case FB_Targets:
    141         m->PrintMessage("HV Feedback: New targets set, switching off.\n");
    142         FBMode = FB_Off;
    143         break;
    144       case FB_ResponseFirst:
    145         FBMode = FB_ResponseSecond;
    146         m->PrintMessage("HV Feedback: Setting second voltage %f for response measurement, acquiring data.\n", Voltage2);
    147         break;
    148       case FB_ResponseSecond:
    149         m->PrintMessage("HV Feedback: Response measurements finished, switching off.\n");
    150         FBMode = FB_Off;
    151         break;
    152       default: break;  // to suppress warning abount not handled enumeration value
    153     }                   
    154     ClearAverages();
    155     return true;
    156   }
    157   else return false;   
    158 }
    159 
     134  switch (FBMode) {
     135    case FB_Active: SlowDataClass->NewEntry("Average");  break;
     136    case FB_Targets: SlowDataClass->NewEntry("Target");  break;
     137    case FB_ResponseSecond: SlowDataClass->NewEntry("Response"); SlowDataClass->AddToEntry("%.3f ",DiffVoltage);  break;
     138    default: break;  // to suppress warning abount not handled enumeration value
     139  }                     
     140
     141  for (i=m->FirstBoard; i<=m->LastBoard; i++)
     142    for (j=0; j<kNumberOfChips; j++)
     143      for (k=0; k<kNumberOfChannels; k++) {
     144        Average[i][j][k] /= Count;
     145        Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count);
     146        switch (FBMode) {
     147          case FB_Active:   // Determine correction from response maxtrix and change voltages
     148            Difference = Target[i][j][k] - Average[i][j][k];
     149            EffectiveGain = Gain*pow(0.5*(1+(Difference/Sigma[i][j][k]-1)/(Difference/Sigma[i][j][k]+1)),2);
     150            Correction = -Difference*Response[i][j][k]*EffectiveGain;
     151            if(Correction!=0 && Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) {
     152              printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f    Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
     153              SlowDataClass->AddToEntry("%d %d %d %.3f %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k],Correction);
     154              if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
     155              else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);
     156            }
     157            break;
     158          case FB_Targets:  // Take average as new targets 
     159            Target[i][j][k] = Average[i][j][k];
     160            SlowDataClass->AddToEntry("%d %d %d %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k]);
     161            break;
     162          case FB_ResponseFirst:  // First point of response measurement done 
     163            Buffer[i][j][k] = Average[i][j][k];
     164            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);
     165            break;
     166          case FB_ResponseSecond: // Determine response from signal variation
     167            if(Buffer[i][j][k] == Average[i][j][k]) {
     168              m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k);
     169              Response[i][j][k] = 0;
     170            }
     171            else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]);
     172            SlowDataClass->AddToEntry("%d %d %d %.3f ", i,j,k,Response[i][j][k]);
     173            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2);
     174            break;
     175          default: break;  // to suppress warning abount not handled enumeration value
     176        }                       
     177      }
     178
     179  switch (FBMode) {
     180    case FB_Targets:
     181      m->PrintMessage("HV Feedback: New targets set, switching off.\n");
     182      FBMode = FB_Off;
     183      break;
     184    case FB_ResponseFirst:
     185      FBMode = FB_ResponseSecond;
     186      m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage);
     187      break;
     188    case FB_ResponseSecond:
     189      m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n");
     190      FBMode = FB_Off;
     191      break;
     192    default: break;  // to suppress warning abount not handled enumeration value
     193  }
     194  ClearAverages();
     195  return true; 
     196}
     197
     198//
    160199// Clear average values and event counter
     200//
    161201void HVFeedback::ClearAverages() {
    162202  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    163203    for (int j=0; j<kNumberOfChips; j++)
    164       for (int k=0; k<kNumberOfChannels; k++) Average[i][j][k] = 0;
     204      for (int k=0; k<kNumberOfChannels; k++) {
     205        Average[i][j][k] = 0.0;
     206        Sigma[i][j][k] = 0.0;
     207      }
    165208  Count = 0;
    166209}
    167210
     211//
    168212// Number of events to accumulate before correction acts
     213//
    169214void HVFeedback::SetNumAverages(unsigned int Averages) {
    170215  NumAverages = Averages;
    171216}
    172217
     218//
    173219// Get requested number of events
     220//
    174221unsigned int HVFeedback::GetNumAverages() {
    175222  return NumAverages;
    176223}
    177224
     225//
    178226// Set feedback gain
     227//
    179228void HVFeedback::SetGain(float FBGain) {
    180229  Gain = FBGain;
    181230}
    182231
     232//
    183233// Get feedback gain
     234//
    184235float HVFeedback::GetGain() {
    185236  return Gain;
    186237}
    187238
     239//
    188240// Set feedback mode and clear averages
     241//
    189242void HVFeedback::SetFBMode(FBState Mode) {
    190243  if(Mode==FB_ResponseFirst || Mode==FB_ResponseFirst)
     
    196249}
    197250
     251//
    198252// Set feedback mode and clear averages
     253//
    199254FBState HVFeedback::GetFBMode() {
    200255  switch (FBMode) {
     
    208263}
    209264
     265//
    210266// Return current number of events
     267//
    211268unsigned int HVFeedback::GetCurrentCount() {
    212269  return Count;
    213270}
    214271
     272//
    215273// Set target values
     274//
    216275void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) {
    217276  if(Board<m->NumCMCBoards && Chip<kNumberOfChips && Channel<kNumberOfChannels)
     
    220279}
    221280
     281//
    222282// Print target values
     283//
    223284void HVFeedback::GetTargets() {
    224285  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     
    228289}
    229290
     291//
    230292// Measure response matrix
    231 void HVFeedback::MeasureResponse(float U1, float U2) {
    232 
    233   if (U2 == 0)
    234     m->PrintMessage("HV Feedback: Error, econd voltage must not be zero.\n");
     293//
     294void HVFeedback::MeasureResponse(float U) {
     295
     296  if (U==0) m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n");
    235297  else {
    236298    for (int i=m->FirstBoard; i<=m->LastBoard; i++)
     
    238300        for (int k=0; k<kNumberOfChannels-2; k++) {
    239301          if(PixMap->DRS_to_Pixel(i,j,k).empty()) m->PrintMessage("Could not find pixel ID of board %d, chip %d, channel %d\n",i,j,k);
    240           else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), U1);
     302          else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);
    241303        }
    242     Voltage1 = U1;   Voltage2 = U2;
     304    DiffVoltage = U;
    243305    FBMode = FB_ResponseFirst;
    244306    ClearAverages(); 
    245     m->PrintMessage("HV Feedback: Setting first voltage  %f for response measurement, acquiring data.\n",U1);
    246   }
    247 }
    248 
     307    m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2);
     308  }
     309}
     310
     311//
    249312// Print response values
     313//
    250314void HVFeedback::GetResponse() {
    251315  for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    252316    for (int j=0; j<kNumberOfChips; j++)
    253317      for (int k=0; k<kNumberOfChannels; k++)
    254          m->PrintMessage("Board %d, chip %d, channel %d: %f\n",i,j,k,Response[i][j][k]);
    255 }
    256 
     318         m->PrintMessage("Board %d, chip %d, channel %d: %.3f\n",i,j,k,Response[i][j][k]);
     319}
     320
     321//
    257322// Write commmand to socket
     323//
    258324bool HVFeedback::WriteHVCommand(const char *Format, ...) {
    259325  char Textbuffer[MAX_COM_SIZE];
     
    263329  do {
    264330    va_list ArgumentPointer;  va_start(ArgumentPointer, Format);
    265     vsprintf(Textbuffer, Format, ArgumentPointer);
    266 
    267     printf("%s", Textbuffer);
     331    vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
     332
    268333    // Write command to socket
    269334    if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) {
     
    295360}
    296361
     362//
    297363// Print feedback configuration
     364//
    298365void HVFeedback::PrintConfig() {
    299366  m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n"
    300367        "LedTrigSample: %d\tLedTrigThreshold: %.2f\n"
    301368        "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n"
    302         "HVControlServer: %s\tHVControlPort: %d\n"
     369        "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n"
    303370        "MaxCmdAckDelay: %d\n",
    304371    fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample,
    305372    fLedTrigThreshold, fLedSignalSample, fLedBaselineSample,
    306     fDefaultNumAverage, fHVControlServer, fHVControlPort, fMaxCmdAckDelay);
    307 }
     373    fDefaultNumAverage, fIntHalfWidth, fHVControlServer, fHVControlPort, fMaxCmdAckDelay);
     374}
Note: See TracChangeset for help on using the changeset viewer.