pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestIV.cc
1 #include <cstdlib>
2 #include <algorithm>
3 #include <iostream>
4 #include <fstream>
5 
6 #include <TH1.h>
7 #include <TMath.h>
8 #include <TTime.h>
9 #include <TPad.h>
10 
11 #include "PixTestIV.hh"
12 #include "log.h"
13 #include "helper.h"
14 #ifdef BUILD_HV
15 #include "hvsupply.h"
16 #endif
17 
18 using namespace pxar;
19 using namespace std;
20 
21 ClassImp(PixTestIV)
22 
23 // ----------------------------------------------------------------------
24 PixTestIV::PixTestIV(PixSetup *a, string name) : PixTest(a, name),
25  fParVoltageStart(0),
26  fParVoltageStop(150),
27  fParVoltageStep(5),
28  fParDelay(1),
29  fParCompliance(100),
30  fStop(false),
31  fParPort(""){
32  PixTest::init();
33  init();
34 }
35 
36 // ----------------------------------------------------------------------
37 PixTestIV::PixTestIV() : PixTest() {}
38 
39 
40 // ----------------------------------------------------------------------
41 bool PixTestIV::setParameter(string parName, string sval) {
42  bool found(false);
43 
44  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
45  for (unsigned int i = 0; i < fParameters.size(); ++i) {
46  if (fParameters[i].first == parName) {
47  found = true;
48  sval.erase(remove(sval.begin(), sval.end(), ' '), sval.end());
49  if(!parName.compare("voltagestart")) {
50  fParVoltageStart = atof(sval.c_str());
51  }
52  if(!parName.compare("voltagestop")) {
53  fParVoltageStop = atof(sval.c_str());
54  }
55  if(!parName.compare("voltagestep")) {
56  fParVoltageStep = fabs(atof(sval.c_str()));
57  }
58  if(!parName.compare("delay(seconds)")) {
59  fParDelay = atof(sval.c_str());
60  }
61  if(!parName.compare("port")) {
62  fParPort = sval;
63  }
64  if(!parName.compare("compliance(ua)")) {
65  fParCompliance = atof(sval.c_str());
66  }
67  setToolTips();
68  break;
69  }
70  }
71  return found;
72 }
73 
74 // ----------------------------------------------------------------------
75 void PixTestIV::init() {
76  fDirectory = gFile->GetDirectory( fName.c_str() );
77  if( !fDirectory )
78  fDirectory = gFile->mkdir( fName.c_str() );
79  fDirectory->cd();
80 }
81 
82 // ----------------------------------------------------------------------
83 void PixTestIV::bookHist(string /*name*/) {
84  fDirectory->cd();
85 }
86 
87 // ----------------------------------------------------------------------
88 void PixTestIV::stop() {
89  fStop = true;
90  LOG(logINFO) << "Stop pressed. Ending test.";
91 }
92 
93 
94 // ----------------------------------------------------------------------
95 PixTestIV::~PixTestIV() {
96  LOG(logDEBUG) << "PixTestIV dtor";
97 }
98 
99 // ----------------------------------------------------------------------
101 
102 #ifndef BUILD_HV
103  LOG(logERROR) << "Not built with HV supply support.";
104  return;
105 #else
106 
107  fDirectory->cd();
108 
109  int numMeasurements = ceil(fabs((fParVoltageStart - fParVoltageStop)/fParVoltageStep));
110 
111  TH1D *h1(0);
112  double vMin = min(fParVoltageStart, fParVoltageStop) - fParVoltageStep*.5;
113  double vMax = vMin + numMeasurements*fParVoltageStep;
114  h1 = bookTH1D("IVcurve", "IV curve", numMeasurements, vMin, vMax);
115  h1->SetMinimum(1.e-2);
116  h1->SetMarkerStyle(20);
117  h1->SetMarkerSize(1.3);
118  h1->SetStats(0.);
119  setTitles(h1, "-U [V]", "-I [uA]");
120 
121  vector<double> voltageMeasurements;
122  vector<double> currentMeasurements;
123  vector<TTimeStamp> timeStamps;
124  double signedStep = (fParVoltageStart < fParVoltageStop) ? fParVoltageStep
125  : -fParVoltageStep;
126  PixTest::update();
127  if(gPad) gPad->SetLogy(true);
128 
129  LOG(logINFO) << "Starting IV curve measurement...";
130  double serialTimeout = (fParDelay > 1.0) ? fParDelay*5 : 5.0;
131  pxar::HVSupply *hv = new pxar::HVSupply(fParPort.c_str(), serialTimeout);
132  hv->setMicroampsLimit(fParCompliance);
133 
134  hv->sweepStart(-fParVoltageStart,-fParVoltageStop,-signedStep,fParDelay);
135  bool aborted;
136  while(hv->sweepRunning()){
137  double voltSet, voltRead, current;
138  aborted = hv->sweepRead(voltSet, voltRead, current);
139  voltageMeasurements.push_back(voltRead);
140  currentMeasurements.push_back(current);
141  h1->Fill(-voltSet, -current*1E6);
142 
143  TTimeStamp ts;
144  ts.Set();
145  timeStamps.push_back(ts);
146 
147  LOG(logINFO) << Form("V = %4f (meas: %+7.2f) I = %4.2e uA %s",
148  voltSet, voltRead, current*1E6, ts.AsString("c"));
149 
150  h1->Draw("p");
151  PixTest::update();
152  gSystem->ProcessEvents();
153  if(fStop) break;
154  }
155  delete hv;
156 
157  if(aborted){
158  LOG(logWARNING) << "Sweep Aborted on Compliance!";
159  }
160  fHistList.push_back(h1);
161  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
162  h1->Draw("p");
163  PixTest::update();
164 
165  writeOutput(voltageMeasurements, currentMeasurements, timeStamps, aborted);
166  LOG(logINFO) << "PixTestIV::doTest() done ";
167 #endif
168 }
169 
170 void PixTestIV::writeOutput(vector<double> &voltageMeasurements,
171  vector<double> &currentMeasurements,
172  vector<TTimeStamp> &timeStamps,
173  bool aborted){
174  ofstream OutputFile;
175  OutputFile.open(Form("%s/ivCurve.log", fPixSetup->getConfigParameters()->getDirectory().c_str()));
176  OutputFile << "# IV test from " << timeStamps[0].AsString("l") << endl;
177  OutputFile << "#Test Parameters:" << endl;
178  OutputFile << "# HV Supply: Keithley2410" << endl;
179  OutputFile << "# Voltage Start: " << fParVoltageStart << endl;
180  OutputFile << "# Voltage Stop: " << fParVoltageStop << endl;
181  OutputFile << "# Voltage Step: " << fParVoltageStep << endl;
182  OutputFile << "# Delay(s): " << fParDelay << endl;
183  OutputFile << "# Compliance(uA): " << fParCompliance << endl;
184  OutputFile << "#voltage(V)\tcurrent(A)\ttimestamp" << endl;
185 
186  unsigned int numMeasurements = voltageMeasurements.size();
187  for (unsigned int i = 0; i < numMeasurements; i++) {
188  OutputFile << Form("%+8.3f\t%+e\t%s", voltageMeasurements[i],
189  currentMeasurements[i],
190  timeStamps[i].AsString("c"))
191  << endl;
192  }
193  if(aborted){
194  OutputFile << "#Sweep was aborted on compliance" << endl;
195  }else{
196  OutputFile << "#Sweep completed Normally" << endl;
197  }
198  OutputFile.close();
199 }
200 
PixSetup * fPixSetup
all necessary stuff in one place
Definition: PixTest.hh:290
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
Definition: PixTest.hh:302
TDirectory * fDirectory
where the root histograms will end up
Definition: PixTest.hh:306
void doTest()
function connected to "DoTest" button of PixTab
Definition: PixTestIV.cc:100
std::list< TH1 * >::iterator fDisplayedHist
pointer to the histogram currently displayed
Definition: PixTest.hh:309
TH1D * bookTH1D(std::string sname, std::string title, int nbins, double xmin, double xmax)
book a TH1D, adding version information to the name and title
Definition: PixTest.cc:895
std::list< TH1 * > fHistList
list of histograms available in PixTab::next and PixTab::previous
Definition: PixTest.hh:307
void setTitles(TH1 *h, const char *sx, const char *sy, float size=0.05, float xoff=1.1, float yoff=1.1, float lsize=0.05, int font=42)
utility to set histogram titles
Definition: PixTest.cc:649
virtual void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
Definition: PixTest.cc:85
void update()
signal to PixTab to update the canvas
Definition: PixTest.cc:569
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
Definition: PixTestIV.cc:41
void init()
sets all test parameters
Definition: PixTest.cc:62