JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
LRBCorrector.cc
Go to the documentation of this file.
1/*!
2 * \file LRBCorrector.cc
3 * \brief Implementation of linear regression blue corrector data handler
4 * \author Michael Vallee
5 * \date 2018-08-01
6 */
7
8#include <iostream>
9
10#include "QwHelicityPattern.h"
11
12#include "LRBCorrector.h"
13
14// Qweak headers
15#include "VQwDataElement.h"
16#include "QwVQWK_Channel.h"
17#include "QwParameterFile.h"
18
19#include <TFile.h>
20#include <TH2.h>
21#include <TKey.h>
22#include <TTree.h>
23#include <TChain.h>
24#include <TObjArray.h>
25#include <TEventList.h>
26
27#include <TMatrixD.h>
28
29// Register this handler with the factory
31
32/// \brief Constructor with name
33LRBCorrector::LRBCorrector(const TString& name):VQwDataHandler(name),
34 fLastCycle(0)
35{
36 ParseSeparator = "_";
37 fKeepRunningSum = kTRUE;
38}
39
41{
43 file.PopValue("slope-file-base", fAlphaFileBase);
44 file.PopValue("slope-file-suff", fAlphaFileSuff);
45 file.PopValue("slope-path", fAlphaFilePath);
46}
47
48Int_t LRBCorrector::LoadChannelMap(const std::string& mapfile)
49{
50 // Open the file
51 QwParameterFile map(mapfile);
52
53 // Read the sections of dependent variables
54 std::pair<EQwHandleType,std::string> type_name;
55
56 // Add independent variables and sensitivities
57 while (map.ReadNextLine()) {
58 // Throw away comments, whitespace, empty lines
59 map.TrimComment();
60 map.TrimWhitespace();
61 if (map.LineIsEmpty()) continue;
62 // Get first token: label (dv or iv), second token is the name like "asym_blah"
63 string primary_token = map.GetNextToken(" ");
64 string current_token = map.GetNextToken(" ");
65 // Parse current token into independent variable type and name
66 type_name = ParseHandledVariable(current_token);
67
68 if (primary_token == "iv") {
69 fIndependentType.push_back(type_name.first);
70 fIndependentName.push_back(type_name.second);
71 fIndependentFull.push_back(current_token);
72 }
73 else if (primary_token == "dv") {
74 fDependentType.push_back(type_name.first);
75 fDependentName.push_back(type_name.second);
76 fDependentFull.push_back(current_token);
77 }
78 else if (primary_token == "treetype") {
79 QwMessage << "Tree Type read, ignoring." << QwLog::endl;
80 }
81 else {
82 QwError << "Function LoadChannelMap in LRBCorrector.cc read in invalid primary_token." << QwLog::endl;
83 }
84 }
85
86 // Construct slope file name
87 std::string SlopeFileName = fAlphaFileBase + run_label.Data() + fAlphaFileSuff;
88 std::string SlopeFilePath = fAlphaFilePath + "/";
89 std::string SlopeFile = SlopeFilePath + SlopeFileName;
90 TString corFileName(SlopeFile);
91
92 QwMessage << "Trying to open " << corFileName << QwLog::endl;
93 TFile* corFile = new TFile(corFileName);
94 if (! corFile->IsOpen()) {
95 QwWarning << "Failed to open " << corFileName << ", slopes NOT found" << QwLog::endl;
96 return 0;
97 }
98
99 // DV names
100 TH1 *dvnames = (TH1 *) corFile->Get("DVname");
101 if (dvnames == 0) {
102 QwWarning << "DV names matrix is null" << QwLog::endl;
103 corFile->Close();
104 return 0;
105 }
106 for (size_t i = 0; i != fDependentName.size(); i++) {
107 TString name = dvnames->GetXaxis()->GetBinLabel(i+1);
108 name.Remove(0, name.First("_") + 1);
109 if (fDependentName[i] != name) {
110 QwWarning << "DV name expected differs from found: "
111 << fDependentName[i] << " != " << name
112 << QwLog::endl;
113 corFile->Close();
114 return 0;
115 }
116 }
117
118 // IV names
119 TH1 *ivnames = (TH1 *) corFile->Get("IVname");
120 if (ivnames == 0) {
121 QwWarning << "IV names matrix is null" << QwLog::endl;
122 corFile->Close();
123 return 0;
124 }
125 for (size_t i = 0; i != fIndependentName.size(); i++) {
126 TString name = ivnames->GetXaxis()->GetBinLabel(i+1);
127 name.Remove(0, name.First("_") + 1);
128 if (fIndependentName[i] != name) {
129 QwWarning << "IV name expected differs from found: "
130 << fIndependentName[i] << " != " << name
131 << QwLog::endl;
132 corFile->Close();
133 return 0;
134 }
135 }
136
137 // Slope matrix
138 TKey* key = corFile->GetKey("slopes");
139 if (key == 0) {
140 QwWarning << "No slope matrix found" << QwLog::endl;
141 corFile->Close();
142 return 0;
143 }
144 QwMessage << "Slope matrix has " << key->GetCycle() << " cycle(s)." << QwLog::endl;
145 fLastCycle = key->GetCycle(); // last cycle
146 for (Short_t cycle=1; cycle<=fLastCycle; cycle++){
147 TKey* key_cycle = corFile->GetKey("slopes", cycle);
148 TMatrixD *alphasM = (TMatrixD *) key_cycle->ReadObj();
149 if (alphasM == 0) {
150 QwWarning << "Slope matrix is null" << QwLog::endl;
151 corFile->Close();
152 return 0;
153 }
154 if (alphasM->GetNrows() != Int_t(fIndependentType.size())) {
155 QwWarning << "Slope matrix has wrong number of rows: "
156 << alphasM->GetNrows() << " != " << fIndependentType.size()
157 << QwLog::endl;
158 corFile->Close();
159 return 0;
160 }
161 if (alphasM->GetNcols() != Int_t(fDependentType.size())) {
162 QwWarning << "Slope matrix has wrong number of cols: "
163 << alphasM->GetNcols() << " != " << fDependentType.size()
164 << QwLog::endl;
165 corFile->Close();
166 return 0;
167 }
168
169 // Assign sensitivities
170 fSensitivity[cycle].resize(fDependentType.size());
171 for (size_t i = 0; i != fDependentType.size(); ++i) {
172 fSensitivity[cycle].at(i).resize(fIndependentType.size());
173 for (size_t j = 0; j != fIndependentType.size(); ++j) {
174 fSensitivity[cycle].at(i).at(j) = -1.0*(*alphasM)(j,i);
175 }
176 }
177 }
178
179 corFile->Close();
180 return 0;
181}
182
183
187{
189
190 // Add independent variables
191 for (size_t iv = 0; iv < fIndependentName.size(); iv++) {
192 // Get the independent variables
193 const VQwHardwareChannel* iv_ptr = 0;
194 iv_ptr = this->RequestExternalPointer(fIndependentFull.at(iv));
195 if (iv_ptr==NULL){
196 switch (fIndependentType.at(iv)) {
197 case kHandleTypeAsym:
198 iv_ptr = asym.RequestExternalPointer(fIndependentName.at(iv));
199 break;
200 case kHandleTypeDiff:
201 iv_ptr = diff.RequestExternalPointer(fIndependentName.at(iv));
202 break;
203 default:
204 QwWarning << "Independent variable for corrector has unknown type."
205 << QwLog::endl;
206 break;
207 }
208 }
209 if (iv_ptr) {
210 //QwMessage << " iv: " << fIndependentName.at(iv) /*<< " (sens = " << fSensitivity.at(dv).at(iv) << ")"*/ << QwLog::endl;
211 fIndependentVar.push_back(iv_ptr);
212 } else {
213 QwWarning << "Independent variable " << fIndependentName.at(iv) << " could not be found."
214 << QwLog::endl;
215 }
216 }
217
218 QwMessage << "In LRBCorrector::ConnectChannels; Number of IVs: " << fIndependentVar.size()
219 << " Number of DVs: " << fDependentVar.size() << QwLog::endl;
220 return 0;
221}
222
223
225 Short_t cycle = fBurstCounter+1;
226 if (fSensitivity.count(cycle) == 0) return;
227 for (size_t i = 0; i < fDependentVar.size(); ++i) {
229 }
230}
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
Parameter file parsing and management.
Definition of the pure virtual base class of all data elements.
Decoding and management for VQWK ADC channels (6x32-bit datawords)
#define REGISTER_DATA_HANDLER_FACTORY(A)
Definition QwFactory.h:263
Linear regression blue corrector data handler class.
Helicity pattern analysis and management.
const VQwHardwareChannel * RequestExternalPointer(const TString &name) const
const VQwHardwareChannel * RequestExternalPointer(const TString &name) const
Retrieve a direct pointer to an external variable Searches for the named variable in external subsyst...
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
Bool_t PopValue(const std::string keyname, T &retvalue)
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
void TrimComment(const char commentchar)
std::string GetNextToken(const std::string &separatorchars)
Get next token as a string.
Abstract base for concrete hardware channels implementing dual-operator pattern.
Linear-regression corrector applying per-burst slopes to data.
std::map< Short_t, std::vector< std::vector< Double_t > > > fSensitivity
std::string fAlphaFilePath
Short_t fLastCycle
std::string fAlphaFileBase
void ParseConfigFile(QwParameterFile &file) override
std::vector< std::string > fIndependentName
void ProcessData() override
Int_t ConnectChannels(QwSubsystemArrayParity &asym, QwSubsystemArrayParity &diff) override
std::vector< EQwHandleType > fIndependentType
std::vector< const VQwHardwareChannel * > fIndependentVar
std::string fAlphaFileSuff
std::vector< std::string > fIndependentFull
Subsystem array container specialized for parity analysis with asymmetry calculations.
void CalcOneOutput(const VQwHardwareChannel *dv, VQwHardwareChannel *output, std::vector< const VQwHardwareChannel * > &ivs, std::vector< Double_t > &sens)
std::vector< std::string > fDependentFull
virtual void ParseConfigFile(QwParameterFile &file)
std::vector< const VQwHardwareChannel * > fDependentVar
VQwDataHandler(const TString &name)
std::string ParseSeparator
Short_t fBurstCounter
When a datahandler array is processed, handlers with lower priority will be processed before handlers...
std::vector< VQwHardwareChannel * > fOutputVar
std::pair< EQwHandleType, std::string > ParseHandledVariable(const std::string &variable)
std::vector< EQwHandleType > fDependentType
std::vector< std::string > fDependentName
virtual Int_t ConnectChannels(QwSubsystemArrayParity &, QwSubsystemArrayParity &asym, QwSubsystemArrayParity &diff)