Home » NUSTAR » NUSTAR PRESPEC » problem with a processor (software-wise)
problem with a processor (software-wise) [message #17144] |
Fri, 08 August 2014 16:23 |
thuyuk
Messages: 68 Registered: July 2014
|
continuous participant |
From: *ific.uv.es
|
|
Hi all,
I want to test an array of data with some 1D conditions and then set output of another array of data when the first data set fulfill the condition.
So, I modified Gate1D.cpp and .hpp as the following:
#include "Gate1D.hpp"
#include <iostream>
#include <cmath>
Gate1D::Gate1D(const std::string &config_dir,
const std::string &name,
const bool no_files)
: Processor(name, config_dir, no_files, std::vector<int>())
{
// make all the in/outputs, parameters and coefficients
// known by name.
NAME_PARAMETER(num_channels);
init();
read_parameters();
NAME_CONDITION_ARRAY(reference_gate, Window1D, parameter(num_channels));
NAME_INPUT_ARRAY(value, parameter(num_channels));
NAME_INPUT_ARRAY(value2test, parameter(num_channels));
NAME_OUTPUT_ARRAY(GatedValue, parameter(num_channels));
init();
read_conditions();
}
Gate1D::~Gate1D()
{
}
void Gate1D::process(prespec::viscon::Interface &viscon_interface, int trigger)
{
int chnr = parameter(num_channels);
for (int i = 0; i<chnr; i++)
{
double left_gate = condition_array(reference_gate, i, 0);
double right_gate = condition_array(reference_gate, i, 1);
if(input_array_value(value, i) == 0 && input_array_value(value2test, i) == 0 )
return;
if (input_array_value(value2test, i) > left_gate && input_array_value(value2test, i) < right_gate)
{
double girdi = input_array_value(value, i);
fill_output_array(GatedValue, i, girdi);
}
}
}
I created required Processor.par and Processor.con files which have parameter and the conditions, respectively.
When I want to run this processor, I get the following error:
go4analysis: prespec/process/Processor.cpp:665: const double& prespec::process::Processor::input_array_value(int, int): Assertion `input_arrays_[channel].size() > i' failed.
I checked if any of input_array_value requests data from any of the channel which has a number that is out of range of the array, but I couldn't see it.
If anyone could tell me what seems to be the problem, I would be grateful.
Thanks!
Tayfun
|
|
|
|
Re: problem with a processor (software-wise) [message #17153 is a reply to message #17152] |
Mon, 11 August 2014 11:56 |
thuyuk
Messages: 68 Registered: July 2014
|
continuous participant |
From: *ific.uv.es
|
|
Hi Michael,
Thanks for the suggestions.
You are right, I will try to create a new processor next time. But, especially for my unique case, I checked first if this processor is used in any other config file, and it is not. So, I didn't expect to see any complications in the other parts of the analysis.
Regarding to your suggestion, using UTILS/ArrayFilter, it doesn't do what I need. I want a put a condition on an array, and if the condition is fulfilled, I want to get the output of another array.
Thank you!
Tayfun
|
|
|
Re: problem with a processor (software-wise) [message #17154 is a reply to message #17144] |
Mon, 11 August 2014 13:48 |
miree
Messages: 71 Registered: June 2014
|
continuous participant |
From: *ikp.physik.tu-darmstadt.de
|
|
Hi Tayfun,
this post is related to the error message Assertion `input_arrays_[channel].size() > i' failed .
If you want to write processors with arrays, you need to know the structure of an Array. This is explained in the tutorial.pdf in Section 4.2 "Elder Arrays: Writing a DSSSD Processor". I'll try to point out the relevant thing:
Arrays are composed of N entries, where N can be different for each event. If an array is defined by
NAME_INPUT_ARRAY(my_array, 4) // 4 different indices allowed: 0,1,2,3
It can look like this: (input_array_size(my_array) == 4)
|entry0 | entry1 | entry2 | entry3 |
-------------------------------------------
index | 1 | 3 | 2 | 3 |
value | 3.2 | 100.5 | 3.3 | 234.5 |
-------------------------------------------
Or it can look like this: (input_array_size(my_array) == 6)
|entry0 | entry1 | entry2 | entry3 | entry4 | entry5 |
-------------------------------------------------------------
index | 3 | 0 | 1 | 2 | 2 | 1 |
value | 3.2 | 100.5 | 3.3 | 234.5 | 150.1 | 3.14 |
--------------------------------------------------------------
Or it can be empty: (input_array_size(my_array) == 0)
|
--------
index |
value |
--------
The index field will only contain numbers 0,1,2 or 3. It can have an arbitrary number of entries. Each index may come zero or one or many times. Each entry has one value.
The meaning of the index depends on the context. It can be the channel of MultihitTDC, the crystalID of a HPGe-ARRAY, or the LYCCA-module number.
The correct way to loop over an array is like this:
int N = input_array_size(my_array); // N can be any positive integer or zero
for (int i = 0; i < N; ++i)
{
int index = input_array_index(my_array, i); // index refers to the index of the i-th array entry
double value = input_array_value(my_array, i); // value refers to the value of the i-th array entry
// do something with the value and the index
// .. for example testing
}
The assertion failure is caused by accessing an entry that is beyond the size of the array.
Example: If you get an array with 3 entries and you call entry 5, it will not work.
input_array_index(my_array, 5); // this will cause an assertion failure if the number of entries is smaller than 6
That's it
There are a few traps that can happen if you are new to that. Looping over an array is one of them.
So don't hesitate to ask.
Also, there is a possibility to make the condition test by calling the function 'condition_valid'
for( //...
{
int index = input_array_index(my_array, i);
double value = input_array_value(my_array, i);
//...
// the following works if 'reference_gate' is defined
// with 'NAME_CONDITION_ARRAY(reference_gate, Window1D, parameter(num_channels))'
if (condition_valid(value, reference_gate, index))
{
//...
}
}
Best regards,
Michael
[Updated on: Mon, 11 August 2014 14:09] Report message to a moderator
|
|
|
|
Re: problem with a processor (software-wise) [message #17167 is a reply to message #17144] |
Wed, 13 August 2014 12:32 |
thuyuk
Messages: 68 Registered: July 2014
|
continuous participant |
From: *ific.uv.es
|
|
Hi Michael,
Thank you for the explanation on how arrays work in the code, although I read this part of the tutorial before, it's useful to have it here if somebody wants to get it easier.
I searched through the available processors in plugins/UTILS, but, I couldn't find one or a combination of them to do what I want to do.
So, I followed your suggestion, and created another processor. Please find below how it looks like:
This the cpp:
#include "ArraysWithCondition.hpp"
#include <iostream>
#include <cmath>
ArraysWithCondition::ArraysWithCondition(const std::string &config_dir,
const std::string &name,
const bool no_files)
: Processor(name, config_dir, no_files, std::vector<int>())
{
// make all the in/outputs, parameters and coefficients
// known by name.
NAME_INPUT_ARRAY(value1, 7);
NAME_INPUT_ARRAY(value2, 7);
NAME_OUTPUT_ARRAY(GatedValue, 7);
NAME_CONDITION_ARRAY(gate, Window1D, 7);
init();
read_conditions();
}
ArraysWithCondition::~ArraysWithCondition()
{
}
void ArraysWithCondition::process(prespec::viscon::Interface &viscon_interface, int trigger)
{
for(int i = 0; i < input_array_size(value1); i++)
{
int index = input_array_index(value1, i);
double val2 = input_array_value(value2, index);
double val1 = input_array_value(value1, index);
double left_gate = condition_array(gate, index, 0);
double right_gate = condition_array(gate, index, 1);
if(val2 < right_gate && val2 > left_gate)
{
fill_output_array(GatedValue, index, val1);
}
}
}
and the hpp:
#ifndef UTILS_ArraysWithCondition_HPP_
#define UTILS_ArraysWithCondition_HPP_
#include <prespec/process/Processor.hpp>
//! @brief A processor that evaluates the information coming from a
//! thin circular plastic membrane detectors, surrounded by
//! many photomultipliers. These detectors are used in the
//! Lycca time of flight subsystem. WTF!!!!! wrong doc!
//!
//! It evaluates the time of the particle impact on the membrane, given
//! the particle position (deduced by other tracking detectors).
//! If this information is missing, the processor tries to deduce the
//! impact position from the time information. That is possible with an
//! accuracy of between (6-10 milimeters).
class ArraysWithCondition : public prespec::process::Processor
{
public:
ArraysWithCondition(const std::string &config_dir,
const std::string &name,
const bool no_files = false);
~ArraysWithCondition();
virtual void process(prespec::viscon::Interface &viscon_interface, int trigger);
double analyze(double x_particle, double y_particle, bool find_position = false);
// the inputs to this processor
enum InputArray
{
value1,
value2,
};
// the outputs of this processor
enum OutputArray
{
GatedValue,
};
enum Conditions
{
gate,
};
};
#endif
This the part in Store.config:
processor HighLevel/particle/incoming/MusicPileUp UTILS.ArraysWithCondition
value1[0:6] <- MuiscPileupCor.music[0:6]
value2[0:6] <- MuiscPileupCor.music[8:14]
display GatedValue
end
And this is how the condition file looks like:
gate[0] 25 160
gate[1] 25 160
gate[2] 25 160
gate[3] 25 160
gate[4] 25 160
gate[5] 25 160
gate[6] 25 160
Well, with these files, the compilation is done without errors. But when I want to run this processor, I get this:
prespec/process/Processor.cpp:665: const double& prespec::process::Processor::input_array_value(int, int): Assertion `input_arrays_[channel].size() > i' failed.
First of all, I looked through the written processors, and couldn't find one to process the MUSIC Pile up data. Second, I have no idea how to process these data, due to the high counting rate, we possibly suffer because of the pile-up in MUSIC, which makes noise in the higher Z region in the ion selection in FRS. So this code intents to put a 1-D gate on the peaks that appear on the spectra of the last 8 channels of the MuiscPileUp Crate, and accept the data from the first 8 channels with this condition.
Maybe I'm wrong, maybe this is not the way to process these data, this is another subject to discuss, but I don't see the reason why the code fails with this kind of error message. The array size is 7 in this case, because two of the channels are missing in the crate. I suppose to fill 7 indices of the input arrays, but why I cannot ask the input value inside any of them?
|
|
|
Re: problem with a processor (software-wise) [message #17177 is a reply to message #17167] |
Wed, 13 August 2014 18:10 |
miree
Messages: 71 Registered: June 2014
|
continuous participant |
From: *ikp.physik.tu-darmstadt.de
|
|
Hi Tayfun,
I never was looking in detail to the pile-up correcting readout of the MUSIC. First of all: Only one of the two MUSICS was read out with the pile-up correction module. The other one was read out in the conventional way. The pile-up correction readout is done with a SIS3302 digitizer from Struck with a special firmware from KVI Groningen. This digitizer has 8 channels for incoming signals.
The unpacker delivers for each of the channels an amplitude (having indices from 0 to 7), and time information (having indices ranging from 8 to 15, where (index-8) will tell you the module channel). Or, in other words: you get 16 output channels (or indices), where the first half contains amplitude information, the second half contains time information.
This module is multi-hit capable, that means that you can have several hits in each channel. You need to select somehow the "good" hit if there are is more than one hit.
One thing that you could do in addition: check the correlation of the SIS-MUSIC amplitudes with the amplitudes from the classical music readout of the other MUSIC. I'have seen an experiment, where there was no correlation at all between the SIS and classical readout.
Regarding the error message in the implementation of your processor. I've written the code as I think it should work in a verbose manner, to point out what is causing the problem in your implementation:
// check first if both arrays have the same number of entries
if (input_array_size(value1) == input_array_size(value2))
{
for (int i = 0; i < input_array_size(value1); ++i)
{
// At this point, your code has a problem, because you use "index" instead of "i".
// The second parameter in the functions input_array_index/input_array_value
// must not exceed the size of the array (i.e. the number of entries of the array)
// Otherwise you'll get an assertion failure.
int index_of_ith_entry_in_value1 = input_array_index(value1, i);
double value_of_ith_entry_in_value1 = input_array_value(value1, i);
int index_of_ith_entry_in_value2 = input_array_index(value2, i);
double value_of_ith_entry_in_value2 = input_array_value(value2, i);
// eventually, you want to check if the indices are the same
if (index_of_ith_entry_in_value1 == index_of_ith_entry_in_value2)
{
if (condition_valid(value_of_ith_entry_in_value2, gate, index_of_ith_entry_in_value1))
{
fill_output_array(GatedValue, index_of_ith_entry_in_value2, value_of_ith_entry_in_value1)
}
}
}
}
Just keep in mind the following: Index of an array entry index_of_ith_entry_in_value1 is something different than the entry number i. Mixing up these two things causes your code to stop with an assertion failure.
|
|
|
|
Goto Forum:
Current Time: Thu Dec 05 07:50:01 CET 2024
Total time taken to generate the page: 0.00764 seconds
|